I created a flutter file containing js following the bi doc “https://learn.microsoft.com/en-us/javascript/api/overview/powerbi/mobile” and made the webview following the steps in the doc “webview_flutter 4.7 . 0”
However, I can’t proceed after this part, I can’t display the Bi with the indicated parameters
Importantly, I need to display the bi in mobile mode, the way I found it was using “layoutType: models.LayoutType.MobilePortrait,”
I need to display this link as a webview in portable mode and take the address using the “embedUrl” variable and present it in the iframe
problem presented “Uncaught TypeError: Cannot read properties of undefined (reading ‘models’)”, Did not find frame
I already tried putting the iframe this way too
“<iframe title=”test mobile” width=”1024″ height=”1060″ frameborder=”0″ allowFullScreen=”true” src=”{{embedUrl}}”></iframe>”
but it still doesn’t make the call, I already tried using flutter_inappwebview 6.0.0 but I also didn’t get any different results
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
void main() => runApp(const MaterialApp(home: WebViewExample(), debugShowCheckedModeBanner: false));
const String kLocalExamplePage = '''
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Bi</title>
</head>
<body>
<div id="embedContainer">
<iframe title="test mobile" width="1024" height="1060" frameborder="0" allowFullScreen="true"></iframe>
</div>
<script>
let loadedResolve, reportLoaded = new Promise((res, rej) => { loadedResolve = res; });
let renderedResolve, reportRendered = new Promise((res, rej) => { renderedResolve = res; });
models = window['powerbi-client'].models;
// Read embed application token
let accessToken = EMBED_ACCESS_TOKEN;
// Read embed URL
let embedUrl = 'https://app.powerbi.com/view?r=eyJrIjoiYzZmM2ViNGEtNzI2OS00YTUyLThjMDUtNTViOWU5ZTAyN2IwIiwidCI6ImM1ZDI4NTZmLWJlOTYtNGQwZi1hY2FiLWZlOTJkZTY2MjhiZCJ9';
document.querySelector('#embedContainer iframe').src = embedUrl;
// Read embed type from radio
let tokenType = TOKEN_TYPE;
// We give All permissions to demonstrate switching between View and Edit mode and saving report.
let permissions = models.Permissions.All;
let config = {
type: 'report',
tokenType: tokenType == '0' ? models.TokenType.Aad : models.TokenType.Embed,
accessToken: accessToken,
embedUrl: embedUrl,
id: embedReportId,
permissions: permissions,
settings: {
layoutType: models.LayoutType.MobilePortrait,
panes: {
filters: {
visible: false
},
pageNavigation: {
visible: false
}
},
bars: {
statusBar: {
visible: false
}
}
}
};
// Get a reference to the embedded report HTML element
let embedContainer = document.querySelector('#embedContainer')[0];
// Embed the report and display it within the div container.
report = powerbi.embed(embedContainer, config);
// report.off removes all event handlers for a specific event
report.off("loaded");
// report.on will add an event handler
report.on("loaded", function () {
loadedResolve();
report.off("loaded");
});
// report.off removes all event handlers for a specific event
report.off("error");
report.on("error", function (event) {
console.log(event.detail);
});
// report.off removes all event handlers for a specific event
report.off("rendered");
// report.on will add an event handler
report.on("rendered", function () {
renderedResolve();
report.off("rendered");
});
</script>
</body>
</html>
''';
class WebViewExample extends StatefulWidget {
const WebViewExample({super.key});
@override
State<WebViewExample> createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
late final WebViewController _controller;
@override
void initState() {
super.initState();
// #docregion platform_features
late final PlatformWebViewControllerCreationParams params;
if (WebViewPlatform.instance is WebKitWebViewPlatform) {
params = WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
);
} else {
params = const PlatformWebViewControllerCreationParams();
}
final WebViewController controller = WebViewController.fromPlatformCreationParams(params);
// #enddocregion platform_features
controller
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
debugPrint('WebView is loading (progress : $progress%)');
},
onPageStarted: (String url) {
debugPrint('Page started loading: $url');
},
onPageFinished: (String url) {
debugPrint('Page finished loading: $url');
},
onWebResourceError: (WebResourceError error) {
debugPrint('''
Page resource error:
code: ${error.errorCode}
description: ${error.description}
errorType: ${error.errorType}
isForMainFrame: ${error.isForMainFrame}
''');
},
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
debugPrint('blocking navigation to ${request.url}');
return NavigationDecision.prevent;
}
debugPrint('allowing navigation to ${request.url}');
return NavigationDecision.navigate;
},
onUrlChange: (UrlChange change) {
debugPrint('url change to ${change.url}');
},
),
)
..addJavaScriptChannel(
'Toaster',
onMessageReceived: (JavaScriptMessage message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
},
)
..loadHtmlString(kLocalExamplePage);
// #docregion platform_features
if (controller.platform is AndroidWebViewController) {
AndroidWebViewController.enableDebugging(true);
(controller.platform as AndroidWebViewController).setMediaPlaybackRequiresUserGesture(false);
}
// #enddocregion platform_features
_controller = controller;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
backgroundColor: Colors.green.shade700,
title: const Text(
'test Bi',
style: TextStyle(color: Colors.white),
),
),
body: WebViewWidget(controller: _controller),
);
}
}
Eduardo Henrique is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.