Access external script in meteor blaze Template.events - javascript

I have this in my client/templates/main.html:
<head>
<title>app boil</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<script src="https://cdnjs.cloudflare.com/ajax/libs/quickblox/2.4.0/quickblox.min.js"></script>
</head>
So I am calling the quickblox api. This provides a QB object.
I have now client/templates/quickblox/quickbloxcall.js which has this code:
import { Template } from 'meteor/templating';
import './quickbloxcall.html'
Template.quickbloxcall.onRendered(function () {
console.log(QB.createSession);
});
Template.quickbloxcall.events({
'submit .quickblox-form'(event) {
var user = {
id: 4448514,
name: 'chatuserweb1',
login: 'chatuserweb1',
pass: 'chatuserweb1'
};
QB.createSession({login: user.login, password: user.pass}, function(err, res) {
if (res) {
QB.chat.connect({userId: user.id, password: user.pass}, function(err, roster) {
if (err) {
console.log(err);
} else {
/*
* (Object) roster - The user contact list
* roster = {
* '1126541': {subscription: 'both', ask: null}, // you and user with ID 1126541 subscribed to each other.
* '1126542': {subscription: 'none', ask: null}, // you don't have subscription but user maybe has
* '1126543': {subscription: 'none', ask: 'subscribe'}, // you haven't had subscription earlier but now you asked for it
* };
*/
}
});
}else{
console.log(err);
}
});
},
});
In above code, when I submit form, I get this error in console:
Uncaught TypeError: Cannot read property 'createSession' of undefined(…)
So this means that the QB object is not accessible inside Template.quickblox.events submit event handler.
However in console.log() I get this:
function (params, callback) {
this.auth.createSession(params, callback);
}
So this means that the Template.quickbloxcall.onRendered is properly loading the QB object.
How do I access this external script in Template.quickblox.events?

What you're seeing on the console does confirm that QB.createSession exists. But see that within that createSession call is a call to another createSession!
That is, I think you'll find that this.auth inside Qb.createSession is the object that's undefined, and the unavailable createSession belongs to auth (undefined), not QB (defined).
This will happen if you haven't run QB.init before calling QB.createSession. init is explained a bit in the QuickBlox JavaScript SDK docs here.

Related

How to create new property in google analytics using javascript code

This is my first time using analytics api to create new property
I got the below code from here
developers.google.com/analytics/devguides/config/mgmt/v3/mgmtReference/management/webproperties/insert
window.onload = function insertProperty() {
var request = gapi.client.analytics.management.webproperties.insert(
{
'accountId': '123456789',
'resource': {
'websiteUrl': 'http://www.examplepetstore.com',
'name': 'Example Store'
}
});
request.execute(function (response) { console.log(response);});
}
<script src="https://apis.google.com/js/api.js"></script>
when i run the code with valid account id ex:'123456789'
I am getting this error
Uncaught TypeError: Cannot read properties of undefined (reading 'analytics') at insertProperty
what should i do to create new property using this code
The below code is the setup of authorization and rest code
// Replace with your client ID from the developer console.
var CLIENT_ID = '';
// Set authorized scope.
var SCOPES = ['https://www.googleapis.com/auth/analytics.readonly'];
function authorize(event) {
// Handles the authorization flow.
// `immediate` should be false when invoked from the button click.
var useImmdiate = event ? false : true;
var authData = {
client_id: CLIENT_ID,
scope: SCOPES,
immediate: useImmdiate
};
gapi.auth.authorize(authData, function(response) {
var authButton = document.getElementById('auth-button');
if (response.error) {
authButton.hidden = false;
}
else {
authButton.hidden = true;
queryAccounts();
}
});
}
function queryAccounts() {
// Load the Google Analytics client library.
gapi.client.load('analytics', 'v3').then(function() {
// Get a list of all Google Analytics accounts for this user
gapi.client.analytics.management.accounts.list().then(handleAccounts);
});
}
function handleAccounts(response) {
// Handles the response from the accounts list method.
if (response.result.items && response.result.items.length) {
// Get the first Google Analytics account.
var firstAccountId = response.result.items[0].id;
// Query for properties.
queryProperties(firstAccountId);
} else {
console.log('No accounts found for this user.');
}
}
function queryProperties(accountId) {
// Get a list of all the properties for the account.
gapi.client.analytics.management.webproperties.list(
{'accountId': accountId})
.then(handleProperties)
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
function handleProperties(response) {
// Handles the response from the webproperties list method.
if (response.result.items && response.result.items.length) {
// Get the first Google Analytics account
var firstAccountId = response.result.items[0].accountId;
// Get the first property ID
var firstPropertyId = response.result.items[0].id;
// Query for Views (Profiles).
queryProfiles(firstAccountId, firstPropertyId);
} else {
console.log('No properties found for this user.');
}
}
function queryProfiles(accountId, propertyId) {
// Get a list of all Views (Profiles) for the first property
// of the first Account.
gapi.client.analytics.management.profiles.list({
'accountId': accountId,
'webPropertyId': propertyId
})
.then(handleProfiles)
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
function handleProfiles(response) {
// Handles the response from the profiles list method.
if (response.result.items && response.result.items.length) {
// Get the first View (Profile) ID.
var firstProfileId = response.result.items[0].id;
// Query the Core Reporting API.
queryCoreReportingApi(firstProfileId);
} else {
console.log('No views (profiles) found for this user.');
}
}
function queryCoreReportingApi(profileId) {
// Query the Core Reporting API for the number sessions for
// the past seven days.
gapi.client.analytics.data.ga.get({
'ids': 'ga:' + profileId,
'start-date': '7daysAgo',
'end-date': 'today',
'metrics': 'ga:sessions'
})
.then(function(response) {
var formattedJson = JSON.stringify(response.result, null, 2);
document.getElementById('query-output').value = formattedJson;
})
.then(null, function(err) {
// Log any errors.
console.log(err);
});
}
// Add an event listener to the 'auth-button'.
document.getElementById('auth-button').addEventListener('click', authorize);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello Analytics - A quickstart guide for JavaScript</title>
</head>
<body>
<button id="auth-button" hidden>Authorize</button>
<h1>Hello Analytics</h1>
<textarea cols="80" rows="20" id="query-output"></textarea>
<script src="https://apis.google.com/js/client.js?onload=authorize"></script>
</body>
</html>
yes i did , when i click on Authorize i got this Error {error: {code: 403, message: "Request had insufficient authentication scopes.",…}}
not sure why..?
The developer hasn’t given you access to this app. It’s currently being tested and it hasn’t been verified by Google
The issue is that your project is still in testing, you need to add users who you want to grant permission to test your app.
Go to google cloud console Under consent screen look for the button that says "add Users" add the email of the user you are trying to run the app with.
Understanding Property, Account, and View in Google Analytics
Your Analytics profile consists of 3 different components. They are account, property, and view (if you’re using Universal Analytics).
Here’s a closer look at each of them:
Account: You should have at least one account to access the analytics report.
Property: A property can be a website or a mobile app that you’d like to track in Google Analytics and has a unique tracking ID.
View: A view is the access point for your reports if you’re using Universal Analytics. For example, within a property you can have different views for viewing all the data for your website, viewing only a specific subdomain, like blog.example.com, or viewing only Google Ads traffic. Views do not exist in Google Analytics 4.

reCAPTCHA: Cannot combine methods in JavaScript

I tried to integrate reCAPTCHA v3 to my Login form and applied all the necessary configuration combinations and examples. Here is my implementation based on Documentation page. However, I cannot pass the g-recaptcha-response value to my Java backend. I think the problem is related to combining grecaptcha and submit methods below.
index.html:
<script src="https://www.google.com/recaptcha/api.js?render=reCAPTCHA_site_key"></script>
login.vue:
<a-button class="primary g-recaptcha" <!-- added "g-recaptcha" to the class -->
#click="onSubmit">
Login
</a-button>
onSubmit() {
grecaptcha.ready(function() {
grecaptcha.execute('reCAPTCHA_site_key', {action: 'submit'})
.then(function(token) {
// I move my login block to here ---------------------------------
this.$refs.formContainer.validate((valid) => { // --> throws error
if (valid) {
const params = { email: 'test#test.com', password: '******' };
this.login(params).then((response) => {
// pass "token" value to the backend
});
}
return false;
});
// ---------------------------------------------------------------
});
});
}
},
Although I get the token value properly, the this.$refs.formContainer.validate((valid) line throws "Uncaught (in promise) TypeError: Cannot read property '$refs' of undefined" error. So, how should I combine these methods (grecaptcha.execute and my login block) properly?

How to get a username from response object using Auth0 Lock?

The question is how to get username, which I used to login, back from response object?
I'm creating the Auth0Lock instance by following code:
this._lock = new Auth0Lock(AUTH_CONFIG.clientId, AUTH_CONFIG.domain, AUTH_CONFIG.options);
and then I subscribe on "authenticated" event:
this._lock.on('authenticated', authResult => {
this._lock.getUserInfo(authResult.accessToken, function(error, profile) {
console.log('profile', profile); // --> undefined
if (error) {
// Handle error
}
});
})
I'm logging in by following credentials:
username: john#gmail.com password: 123456
I want to be able to see 'username: john#gmail.com' somewhere in authResult object.
But unfortunately I don't see.
Should I add something in Auth0lock options?
P.S. I've added following code inside the handler of "authenticated" event, but it returns undefined for profile.
I've just added scope: 'openid' into "auth" property of options
options: {
...
auth: {
...
scope: 'openid' <---
}
}

Flutter Webview two way communication with Javascript

I have an html file that I am loading in Flutter webview using flutter_webview_plugin. I am using evalJavascript to call function in my javascript code, meaning flutter(dart)->js. However, I also need some way to communicate back something to flutter(dart) layer, meaning js->flutter(dart).
I have tried using
- webkit.messageHandlers.native
- window.native
to support both platforms(Android,iOS) checking if those are available in JS. But, those comes as undefined. Using following code to get instance of native handler in JS.
typeof webkit !== 'undefined' ? webkit.messageHandlers.native :
window.native;
And even if I get that instance and post message using it, not sure how to handle it in flutter(dart) layer. I may need to use platform channels. Not sure, if I am in the right direction.
Is there any way through which I can do that? I have evaluated interactive_webview plugin. It works fine on Android. But, it has swift versioning issue and don't want to proceed further with that.
Any help would be appreciated.
Here is an example of communication from Javascript code to flutter.
In Flutter build your WebView like :
WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: Set.from([
JavascriptChannel(
name: 'Print',
onMessageReceived: (JavascriptMessage message) {
//This is where you receive message from
//javascript code and handle in Flutter/Dart
//like here, the message is just being printed
//in Run/LogCat window of android studio
print(message.message);
})
]),
onWebViewCreated: (WebViewController w) {
webViewController = w;
},
)
and in Your HTMLfile:
<script type='text/javascript'>
Print.postMessage('Hello World being called from Javascript code');
</script>
When you run this code, you shall be able to see log "Hello World being called from Javascript code" in the LogCat/Run window of android studio.
You can try my plugin flutter_inappbrowser (EDIT: it has been renamed to flutter_inappwebview) and use addJavaScriptHandler({#required String handlerName, #required JavaScriptHandlerCallback callback}) method (see more here).
An example is presented below.
On Flutter side:
...
child: InAppWebView(
initialFile: "assets/index.html",
initialHeaders: {},
initialOptions: InAppWebViewWidgetOptions(
inAppWebViewOptions: InAppWebViewOptions(
debuggingEnabled: true,
)
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
controller.addJavaScriptHandler(handlerName: "mySum", callback: (args) {
// Here you receive all the arguments from the JavaScript side
// that is a List<dynamic>
print("From the JavaScript side:");
print(args);
return args.reduce((curr, next) => curr + next);
});
},
onLoadStart: (InAppWebViewController controller, String url) {
},
onLoadStop: (InAppWebViewController controller, String url) {
},
onConsoleMessage: (InAppWebViewController controller, ConsoleMessage consoleMessage) {
print("console message: ${consoleMessage.message}");
},
),
...
On JavaScript side (for example a local file assets/index.html inside the assets folder):
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Flutter InAppBrowser</title>
...
</head>
<body>
...
<script>
// In order to call window.flutter_inappwebview.callHandler(handlerName <String>, ...args)
// properly, you need to wait and listen the JavaScript event flutterInAppWebViewPlatformReady.
// This event will be dispatched as soon as the platform (Android or iOS) is ready to handle the callHandler method.
window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
// call flutter handler with name 'mySum' and pass one or more arguments
window.flutter_inappwebview.callHandler('mySum', 12, 2, 50).then(function(result) {
// get result from Flutter side. It will be the number 64.
console.log(result);
});
});
</script>
</body>
</html>
On Android Studio logs you will get:
I/flutter (20436): From JavaScript side:
I/flutter (20436): [12, 2, 50]
I/flutter (20436): console message: 64
I want to tell you about how to send messages from flutter WebView to JS:
In JS code you need to bind your function you need to fire to window
const function = () => alert('hello from JS');
window.function = function;
In your code in WebView widget implementation you need to declare onWebViewCreated method like this
WebView(
onWebViewCreated: (WebViewController controller) {},
initialUrl: 'https://url.com',
javascriptMode: JavascriptMode.unrestricted,
)
In class widget declare var _webViewController;
class App extends State<MyApp> {
final _webViewController;
}
In onWebViewCreated write this code
onWebViewCreated: (WebViewController controller) {
_webViewController = controller;
},
Then you can run code like this:
class App extends StatelessWidget {
var _webViewController;
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: WebView(
onWebViewCreated: (WebViewController controller) {
_webViewController = controller;
},
initialUrl: 'https://url.com',
javascriptMode: JavascriptMode.unrestricted,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// When you click at this button youll run js code and youll see alert
_webViewController
.evaluateJavascript('window.function ()');
},
child: Icon(Icons.add),
backgroundColor: Colors.green,
),
),
);
}
}
But what if we want to share this _webViewController instance to other widgets like drawer?
In this case I decided to implement Singleton pattern and store _webViewController instance in it.
So
Singleton class
class Singleton {
WebViewController webViewController;
static final Singleton _singleton = new Singleton._internal();
static Singleton get instance => _singleton;
factory Singleton(WebViewController webViewController) {
_singleton.webViewController = webViewController;
return _singleton;
}
Singleton._internal();
}
Then
onWebViewCreated: (WebViewController controller) {
var singleton = new Singleton(controller);
},
And finally in our Drawer widget i.e. (here you can use whatever widget you want)
class EndDrawer extends StatelessWidget {
final singleton = Singleton.instance;
#override
Widget build(BuildContext context) {
return Drawer(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
SizedBox(
width: 200,
child: FlatButton(
onPressed: () {
singleton.webViewController.evaluateJavascript('window.function()');
Navigator.pop(context); // exit drawer
},
child: Row(
children: <Widget>[
Icon(
Icons.exit_to_app,
color: Colors.redAccent,
),
SizedBox(
width: 30,
),
Text(
'Exit',
style: TextStyle(color: Colors.blueAccent, fontSize: 20),
),
],
),
)),
],
),
);
}
}
If you want to receive messages from JS code to your flutter App you need:
In your js code
window.CHANNEL_NAME.postMessage('Hello from JS');
In your flutter code.
When you're running JavascriptChannel(name: 'CHANNEL_NAME', ...)
flutter bind to your window WebView new MessageChannel with name you wrote in constructor (in this case CHANNEL_NAME)
so when we call window.CHANNEL_NAME.postMessage('Hello from JS'); we recieve a message we sent
WebView(
javascriptChannels: [
JavascriptChannel(name: 'CHANNEL_NAME', onMessageReceived: (message) {
print(message.message);
})
].toSet(),
initialUrl: 'https://url.com',
)
So here we are.
I'm new in flutter code
So if you have another better experience about this you can write in comments to help other people!
Full code example of Javascript callbacks using package flutter_inappwebview:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
InAppWebViewController _webViewController;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('InAppWebView Example'),
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: InAppWebView(
initialData: InAppWebViewInitialData(data: """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
</head>
<body>
<h1>JavaScript Handlers (Channels) TEST</h1>
<button id='test' onclick="window.flutter_inappwebview.callHandler('testFunc');">Test</button>
<button id='testargs' onclick="window.flutter_inappwebview.callHandler('testFuncArgs', 1);">Test with Args</button>
<button id='testreturn' onclick="window.flutter_inappwebview.callHandler('testFuncReturn').then(function(result) { alert(result);});">Test Return</button>
</body>
</html>
"""),
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
)),
onWebViewCreated: (InAppWebViewController controller) {
_webViewController = controller;
_webViewController.addJavaScriptHandler(
handlerName: 'testFunc',
callback: (args) {
print(args);
});
_webViewController.addJavaScriptHandler(
handlerName: 'testFuncArgs',
callback: (args) {
print(args);
});
_webViewController.addJavaScriptHandler(
handlerName: 'testFuncReturn',
callback: (args) {
print(args);
return '2';
});
},
onConsoleMessage: (controller, consoleMessage) {
print(consoleMessage);
},
),
),
])),
),
);
}
}
There are two ways to communicate the answer:
First way From Flutter to the webview (javascript, react...)
From the flutter side (using a button or in a trigger method):
webViewController.evaluateJavascript('fromFlutter("pop")');
This fromFlutter will be the name of the method in your javascript, react, whatever and also you can send text, in this case "pop".
From the javascript side inside the html, in your body label:
<script type="text/javascript">
function fromFlutter(data) {
// Do something
console.log("This is working now!!!");
}
</script>
Second way From your webview (javascript, react...) to Flutter
In your Webview attribute javascriptChannels you can add:
javascriptChannels: Set.from([
JavascriptChannel(
name: 'comunicationname',
onMessageReceived: (JavascriptMessage message) async {
// Here you can take message.message and use
// your string from webview
},
)
]),
From the webview using the same communication name "communicationname" (your can use another name in both places):
window.communicationname.postMessage("native,,,pop,");
Flutter 3.0.5
webview_flutter: ^3.0.4
flutter_js: ^0.5.0+6
Another way to use JavascriptChannels is to tranfer data from the "App" to your Website.
Dart:
JavascriptChannel(
name: 'getFCMToken',
onMessageReceived: (JavascriptMessage message) async {
//print(message.message);
final token = (await FirebaseMessaging.instance.getToken())!;
final script = "var appToken =\"${token }\"";
_webViewController.runJavascript(script);
},
),
html:
<script type = "text/javascript">
window.onload = getFCMToken.postMessage('');
</script>
or Dart(Trigger):
OnPageFinished: (url) async {
try {
final token = (await FirebaseMessaging.instance.getToken())!;
var javascript = "var appToken=\"${token.toString()}\"";
} catch (_) {}
}
so in your website code you have a js var "appToken" wich you can use in PHP or whatever.
If you are using webviewx plugin which support web,ios and android than this is how we can do two way communication.
I have webpage which has index.html and other js,and css pages which I want to display in webview and communicate between flutter and web app.
1. From flutter to js listener
IconButton(
icon: Icon(Icons.developer_mode),
onPressed: () {
webviewController
.evalRawJavascript('window.myFunction()',
inGlobalContext: false)
.then((value) => print(value));
},
)
Note: myFunction is function defined in javascript or html page as below.
function myFunction() {
alert("I am an alert box!");
return 'working';
}
2. From js/html to flutter listener
In html/js add button with listener
function submitClick() {
var data = document.getElementById('data').value;
SubmitCallback(data) //defined in flutter
}
Now In flutter(add dartCallback):
WebViewX(
javascriptMode: JavascriptMode.unrestricted,
initialContent: '<h2> Loading </h2>',
initialSourceType: SourceType.HTML,
onWebViewCreated: (controller) {
webviewController = controller;
_loadHtmlFromAssets();
webviewController.addListener(() {});
},
dartCallBacks: {
DartCallback(
name: 'SubmitCallback',
callBack: (msg) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Submitted $msg successfully')));
},
),
},
)
PS. Happy Coding

JQuery nested $.when ... then statements

I'm trying to do a FreeCodeCamp exercise where I call the Twitch TV API. For each channel I make a call to the API to get the channel data. I then make a subsequent call to get the streaming data. The call for the channel information is wrapped in a $.when ... then loop and seems to work fine. I then added a second call to get the stream data and code does not seem to wait for that call to complete.
$(document).ready(function() {
'use strict';
var dataArray = []; // This holds all the channels that I find. I then sort to get the most popular first.
$.when(
// TODO this should be some sort of loop to make it more flexible
getChannelData("https://api.twitch.tv/kraken/search/channels?api_version=3&q=all&limit=10&offset=0&callback=?") // First 10
).then(function() {
sortData();
displayData();
});
function getChannelData(channelStatement) {
return $.getJSON(channelStatement, function(channelData) {
channelData.channels.forEach(function(element) {
// Get stream details
var channel;
channel = {
logo: (element.logo === null) ? "https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png" : element.logo, // Channel: Url for image
displayName: element.display_name, // Channel: Broadcaster name
channelName: element.name, // Channel: Channel name
url: element.url, // Channel: Used to generate link to twitch page
game: element.game, // Channel: As the name suggests
status: element.status, // Chaneel: Description of the stream
views: element.views, // Channel: As the name suggests
onLine: true
};
//dataArray.push(channel);
var streamUrl = "https://api.twitch.tv/kraken/streams/" + element.name + "?api_version=3&callback=?";
$.when(
getStreamData(streamUrl, channel)
)
.then(function() {
dataArray.push(channel);
});
}); // channel data forEach
});
}
function getStreamData(streamUrl, channel) {
return $.getJSON(streamUrl, function(stream) {
channel.onLine = (stream.stream === null) ? false : true;
});
}
function sortData() {
}
function displayData() {
}
}); // end ready
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
crossorigin="anonymous">
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="style.css">
<title>Twitch TV</title>
</head>
<body>
<div class="container-fluid">
<ol id="twitchList">
</ol>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="TwitchTV.js"></script>
</body>
</html>
This JSBin link shows the code. Line 51 shows the second ajax call.
The code should populate an array and then on completion of all the calls display the data. I appreciate that with a production system waiting for all these calls to complete will lead to a less than idea user experience.
You need to re-oganize it slightly so that the promise you return from getChannelData is waiting on the promises created within your forEach.
function getChannelData(channelStatement) {
return $.getJSON(channelStatement).then(function(channelData) {
return $.when.apply(null, channelData.channels.map(function(element) {
// Get stream details
var channel = {
logo: (element.logo === null) ? "https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png" : element.logo, // Channel: Url for image
displayName: element.display_name, // Channel: Broadcaster name
channelName: element.name, // Channel: Channel name
url: element.url, // Channel: Used to generate link to twitch page
game: element.game, // Channel: As the name suggests
status: element.status, // Chaneel: Description of the stream
views: element.views, // Channel: As the name suggests
onLine: true
};
//dataArray.push(channel);
var streamUrl = "https://api.twitch.tv/kraken/streams/" + element.name + "?api_version=3&callback=?";
return getStreamData(streamUrl, channel);
}); // channel data map
});
}
you would then use it like:
getChannelData(whatever).then(function () {
console.log(arguments); // this is dataArray
});

Categories

Resources