I am trying to load google authentication library using promises, but I fail when I try to call gapi.auth2.getAuthInstance() and return it in promise;
Here's how I am doing this:
var loadPlatform = function ($q) {
var deferred = $q.defer(),
platform = document.createElement('script');
platform.src ='https://apis.google.com/js/platform.js';
platform.type = 'text/javascript';
platform.async = true;
platform.defer = true;
platform.onload = deferred.resolve;
platform.onerror = deferred.reject;
document.body.appendChild(platform);
return deferred.promise;
};
//I return this from other function
return loadPlatform($q)
.then(function () {
var deferred = $q.defer();
gapi.load('auth2', function () {
deferred.resolve(gapi.auth2);
});
return deferred.promise;
})
.then(function (auth2) {
//This function retuns Promise
//https://developers.google.com/identity/sign-in/web/reference#gapiauth2initparams
return auth2.init(params);
})
.then(function (GoogleAuth) {
//Here I should have solved GoogleAuth object
});
Everything works until I return auth2.init(params) then browser freezes.
What's happening here?
I just experienced the same issue.
It seems like you can't chain the init() promise of the auth2 object.
I had to wrap around it to avoid the browser freeze.
return new Promise<void>(resolve => {
gapi.auth2.init({
client_id: this._clientId,
scope: 'profile'
}).then(() => resolve());
})
Also it was interesting that I could not apply the resolve function directly.
.then(resolve);
Update
As said above, the returned object of the init() call is not a promise, it is kind of a wrapper and only returns a real promise once you called the .then method
return gapi.auth2.init({
client_id: this._clientId,
scope: 'profile'
}).then();
// Auth2 only returns a promise, when we chained into the PromiseLike object once.
Related
I try to use the Ionic Storage module to store some values, for example my authentication token :
/**
* Get Token
*/
public get token(): string {
this.storage.get(this.LS_TOKEN).then((val) => {
console.log(val);
this._token.next(val);
console.log( this._token.getValue());
});
return this._token.getValue();
// return 'testtttt';
}
I try multiple things, return directly the value, set the value and return the variable...
But I always got a null, and the thing that is strange is that if I return a string directly it works, when I console.log the val it show the string that I want, but the return is always null..
What am I doing wrong ?
Edit :
In response of the first answer I have tried this :
/**
* Get Token
*/
public get token() {
this.tokenPromise().then(yourToken => {
console.log(yourToken);
return yourToken;
});
}
public tokenPromise() {
return new Promise((resolve, reject) => {
this.storage.get(this.LS_TOKEN).then((val) => {
resolve(val);
}).catch(ex => {
reject(ex);
});
});
}
My problem is the same, in my components when I try to use : console.log(this.sharedService.token);
It's still null
It is not working with your new token() method.
It is still asnychron. Im gonna show you:
public get token() {
return new Promise((resolve, reject)=>{
this.storage.get(this.LS_TOKEN).then((val) => {
resolve(val);
}).catch(ex=>{
reject(ex);
});
});
}
Now you can use your token from the sharedservice like this:
this.sharedService.token.then(token=>{
//use token here;
});
or you can use await, but the function who is calling it, must be async:
async useTokenFromService(){
let token = await this.sharedService.token;
console.log(token);
}
You are getting a Promise from the storage.get() method.
This means it is running asynchron.
You can return Promise.
public get token() {
return new Promise((resolve, reject)=>{
this.storage.get(this.LS_TOKEN).then((val) => {
resolve(val);
}).catch(ex=>{
reject(ex);
});
});
}
And you can receive this with an async function and await the result:
async loadToken(){
let loadedToken = await this.token();
// use your loadedToken here...
}
Or you can use the .then method from the promise like this:
loadToken(){
this.token().then(yourToken=>{
// use the token yourToken here...
});
}
I tried adding an installable hook sails-hook-myoverride that looks like this:
let carryOn = (values, proceed, previous) => _.isFunction(previous) ? previous(values, proceed) : proceed();
module.exports = function (sails) {
return {
initialize: function (cb) {
sails.after(['hook:orm:loaded'], function () {
_.each(sails.models, (model) => {
let previousBeforeUpdate = model.beforeUpdate;
model.beforeUpdate = function (values, proceed) {
console.log("myoverride::beforeUpdate", values);
return carryOn(values, proceed, previousBeforeUpdate);
};
let previousBeforeCreate = model.beforeCreate;
model.beforeCreate = function (values, proceed) {
console.log("myoverride::beforeCreate", values);
return carryOn(values, proceed, previousBeforeCreate);
};
});
cb();
});
}
}
};
Then in my Test model I added both beforeUpdate and beforeCreate methods:
beforeUpdate: function (values, cb) {
console.log('Test::beforeUpdate');
cb();
},
beforeCreate: function (values, cb) {
console.log('Test::beforeCreate');
cb();
}
And then I called POST on http://localhost:1337/test to test it.
Surprisingly, sails printed only Test::beforeCreate and not myoverride::beforeCreate as well, as I was hoping it would.
Google did not help and neither did Sails documentation :(
I'm completely lost at the moment...
OK, apparently, using sails.after(['hook:sockets:loaded'], function () { works for some reason...
maybe is a stupid question but,
when I'm calling api from 'outside' function it always returns undefined,
for example:
actions.js
import axios from 'axios'
export function getProducts() {
axios.get('http://localhost:8000/api/products').then((response) => {
return response;
});
}
and then in a component:
mounted() {
this.products = getProducts();
console.log(this.products);
}
returns undefined
of course when I make a request from component it returns result
mounted() {
axios.get('http://localhost:8000/api/products').then((response) => {
this.products = response;
console.log(this.products);
});
}
Why is this happening and how can I solve this problem?
Thanks
You are returning the response value in the then callback of the axios.get call. However, your getProducts function doesn't return anything.
Simply return the axios.get call:
export function getProducts() {
return axios.get('http://localhost:8000/api/products');
}
Then, the result of getProducts will be the Promise returned by axios.get(). So, you can add a then callback on the result of getProducts and set you this.products that way:
mounted() {
getProducts().then(products => this.products = products);
}
I've built the following event listener which will run the function isValidEmail, passing in a callback function NotInDatabase() which is scheduled to only run after an ajax call is complete. It appears though that NotInDatabase() runs immediately. Any idea why this would be happening?
Event listener:
const bindEvents = (form, inputSelector, errorSelector) => {
const emailInput = document.getElementById('email');
emailInput.addEventListener('blur', function(){
const emailValue = emailInput.value
isValidEmail('http://localhost:3001/user/email/'+emailValue,'data_placeholder', NotInDatabase())
});
}
isValidEmail with callback:
const isValidEmail = (url, data, success) => {
const xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xhr.open('POST', url);
xhr.onreadystatechange = function() {
if (xhr.readyState>3 && xhr.status==200) {
success(xhr.responseText);
}
};
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded', 'Access-Control-Allow-Origin');
xhr.send(data);
return xhr;
}
Here
isValidEmail('http://localhost:3001/user/email/'+emailValue,'data_placeholder', NotInDatabase())
you do not pass NotInDatabase function as a callback into isValidEmail, but pass what it returns because NotInDatabase() is a function call.
Remove () to solve your problem
I created a service called AppService.
Its function getUserPostionOptions is supposed to return an object:
getUserPostionOptions: function (user) {
// PositionOptions.findOne({id:'53f218deed17760200778cfe'}).exec(function (err, positionOptions) {
var positionDirectionsOptions = [1,2,3];
var positionLengthsOptions = [4,5,6];
var object = {
directions:positionDirectionsOptions,
lengths:positionLengthsOptions
};
return object;
// });
}
This works, in my controller positionOptions gets populated correctly:
var positionOptions = AppService.getUserPostionOptions(user);
However, when I uncomment the find query the item is found but the object returns undefined.
Thank in advance for your help
SailsJs ORM (and almost NodeJs database querying methods) uses non-blocking mechanism via callback function. So you have to change your code into:
getUserPostionOptions: function (user, callback) {
PositionOptions.findOne({id:'53f218deed17760200778cfe'}).exec(function (err, positionOptions) {
var positionDirectionsOptions = [1,2,3];
var positionLengthsOptions = [4,5,6];
var object = {
directions:positionDirectionsOptions,
lengths:positionLengthsOptions
};
callback(null, object); // null indicates that your method has no error
});
}
Then just use it:
AppService.getUserPostionOptions(user, function(err, options) {
if (!err) {
sails.log.info("Here is your received data:");
sails.log.info(options);
}
});