Angular2 view not updated after callback function - javascript

I'm using Meteor-Angular2 and slingshot package for uploading images to S3 storage. when returning from the function and assign to binded string, view not updated. (setTimout function is working and updating view, but uploader function not)
export class AdminComponent {
public urlVariable: string = "ynet.co.il";
constructor() {
this.uploader = new Slingshot.Upload("myFileUploads");
setTimeout(() => {
this.urlVariable = "View is updated";
}, 10000);
}
onFileDrop(file: File): void {
console.log('Got file2');
this.uploader.send(file, function (error, downloadUrl) {
if (error) {
// Log service detailed response
}
else {
this.urlVariable = "View not updated";
}
});
}
}

Use arrow functions (() =>) instead of function () to retain the scope of this.
this.uploader.send(file, (error, downloadUrl) => {
if (error) {
// Log service detailed response
}
else {
// now `this.` points to the current class instance
this.urlVariable = "View not updated";
}
});
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Functions/Arrow_functions

this one is working for me: (narrow function+Ngzone)
this.uploader.send(file, (error, downloadUrl) => {
if (error) {
// Log service detailed response
}
else {
// now `this.` points to the current class instance
this._ngZone.run(() => {this.urlVariable = "View not updated"; });
}
});

Related

Async function inside mobx-store not awaiting when called inside my components

in my react native components I call async functions defined inside my mobx stores, however when I call them the code after them inmediatly runs instead of waiting for the async function to end.
In my case "ACTION COMPLETED" appears on console before the axios call is completed...
I call it like this inside my components:
const sendVerify = async () =>
{
try
{
//Tried with await
await root.userStore.getLoggedUser(response.data.user.id);
console.log('ACTION COMPLETED');
//Also tried with then at didn't work
root.userStore.getLoggedUser().then(response => console.log('ACTION COMPLETED'));
}
catch (error)
{
throw error;
}
};
Async function inside UserStore:
export class UserStore
{
root = null;
constructor(root)
{
makeAutoObservable(this, { root: false });
this.root = root;
}
async getLoggedUser(user_id = false)
{
try
{
let url = env.BASE_URL+'/api/auth/sanctum/user';
let params = {};
let response = await http.get(url, {params:params});
return true;
}
catch (error)
{
return false;
throw error;
}
}

How to get callback data outside of a function (AWS SDK)(non async)

I have a function that gets data from AWS:
main.js
const { GetInstancesByName } = require("./functions");
var operationmode = "getinstances";
if (operationmode == "getinstances") {
let getresult = GetInstancesByName(instance);
console.log("(getinstances log)",getresult);
let resultsent = "yes";
callback(getresult);
}
then this is the functions file (functions.js):
functions.js
const GetInstancesByName = function GetInstancesByName(name) {
let ec2 = new AWS.EC2({apiVersion: '2016-11-15'});
//console.log(ec2);
let params = {
Filters: [
{
Name: "tag:Name",
Values: [
name
]
}
]
};
ec2.describeInstances(params, function(err, data) {
if (err)
console.log("error",err, err.stack); // an error occurred
else return data; // successful response
/*
data = {
}
*/
});
return data;
};
I am trying to get the data from the (error , data) in the function. I have tried: setting a var/const/let to the data. the return data at the bottom works but data is empty. I want to get data so I can pass it back in the GetInstancesByName (being used by main.js).
on the main both console.log("(getinstances log)",getresult) and callback(getresult); both return not defined.
Any help would be much appreciated.
Thank You
If you don't want to use async/await, you may pass a callback to GetInstancesByName as follows:
function GetInstancesByName (name, callback) {
// ...
ec2.describeInstances(params, function(err, data) {
if (err) {
console.log("error",err, err.stack); // an error occurred
} else {
callback(data); // successful response
}
});
// ...
}
// In main.js
GetInstancesByName(instance, data => {
// do something with data
});

How to capture Google recaptchaV3 Promise Timeout?

import canUseDOM from '#utils/dist/env/canUseDOM';
declare global {
interface Window {
grecaptcha: any;
}
}
export default async function getRecaptchaTokenExplicit(params: { recaptchaClientId: number }) {
return new Promise(resolve => {
if (canUseDOM && window.grecaptcha) {
const { recaptchaClientId } = params;
window.grecaptcha.ready(() => {
window.grecaptcha
.execute(recaptchaClientId, {
action: 'submit',
})
.then(function(token: string) {
return resolve(token);
});
});
} else {
return resolve('');
}
});
}
Calling await above function, I used to get Timeout console error from recaptcha (found it was because of badge element get removed due to component rendering), but in order to avoid it, how do I capture it and resolve return empty string?
error looks like this:
Since the error is in the promise, have you tried to .catch() it?
window.grecaptcha
.execute(recaptchaClientId, {
action: 'submit',
})
.then(function(token: string) {
resolve(token);
})
.catch(err => {
console.error(err);
resolve('');
});

How to write a simple mock of an API call that returns async

There is this sample application that has a level db Node JS library, but my server doesn't currently have level db installed and I don't need it.
How can I write a simple class that would just mock the API calls.
The store variable is the library I want to mock, and it has 2 API calls:
store.put
store.get
It has 2 API calls:
const store = level('./data/dbname123', { valueEncoding: 'json' });
save() {
debug(`saving id: ${this.id}`);
const properties = attributes.reduce((props, attr) => {
props[attr] = this[attr];
return props;
}, { fields: this.fields });
return new Promise((resolve, reject) => {
store.put(this.id, properties, (error) => {
if (error) { return reject(error); }
resolve(this);
});
});
}
static find(id) {
debug(`fetching id: ${id}`)
return new Promise((resolve, reject) => {
store.get(id, (error, properties) => {
if (error) { return reject(error); }
resolve(new Ticket(properties));
});
});
}
How can I quickly just mock those? I'm not too familiar with this style of JavaScript but it because of the promise wrapper I'm not sure if that is async call or?
You can just create an object with put and get methods on it that simulate what those methods do. Just make sure your functions follow the expected conventions — for example calling the callback with an error as the first argument if there's a problem.
Obviously this can be more involved and there are tools like Sinon that can help if you have to mock existing functions.
For example:
// simple mocks for store.get and store.put
let store = {
put(id, properties, fn){
// add whatever behavior you need and call callback fn
fn(null) // calling with null indicates no error.
},
get(id, fn){
// make some properties
let props = {
someProperties: "Hello",
id: id
}
// call callback
fn(null, props)
}
}
function save() {
return new Promise((resolve, reject) => {
store.put('id', 'properties', (error) => {
if (error) { return reject(error); }
resolve();
});
});
}
function find(id) {
return new Promise((resolve, reject) => {
store.get(id, (error, properties) => {
if (error) { return reject(error); }
resolve(properties);
});
});
}
// try them out
find("21")
.then(console.log)
save()
.then(() => console.log("done"))
Maybe my answer doesn't correspond to your question but to mock your library you can create your own storage
const store = function () {
var data = {};
return {
put: function(id, props, fn) {
data[id] = props;
fn(null);
},
get: function(id, fn) {
fn(null, data[id]);
}
}
}();
If you define your storage like it, you mock your library

Asynchronous call of two functions in Angular 2 using promise

I have the following method in auth.nav.service.ts:
public login () {
this.authService.login();
this.navService.redirectAfterLogin();
}
in nav.service.ts:
public redirectAfterLogin () {
let nav = this.app.getRootNav();
nav.setRoot(TabsPage);
nav.popToRoot();
}
In Auth.service.ts:
public login() {
const client = new Auth0Cordova(auth0Config);
const options = {
scope: 'openid profile offline_access'
};
client.authorize(options, (err, authResult) => {
if(err) {
throw err;
}
this.setIdToken(authResult.idToken);
this.setAccessToken(authResult.accessToken);
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
this.setStorageVariable('expires_at', expiresAt);
this.auth0.client.userInfo(this.accessToken, (err, profile) => {
if(err) {
throw err;
}
profile.user_metadata = profile.user_metadata || {};
this.setStorageVariable('profile', profile);
this.zone.run(() => {
this.user = profile;
});
});
});
}
I want to have the login function ran successfully and the use the RedirectAfterLogin. How can I do that with Promise ? I'm using Angular 2, Ionic-Native 3 and auth0.
I made it work with a promise, and fixing the scope of the variables (this) inside the then scope.
auth.view.service.ts
public login () {
var t = this; // this scope is lost inside the then.
this.authService.login().then(function (response){
t.navService.redirectAfterLogin();
});
}
auth.service.ts
public login () {
return new Promise<any>((resolve, reject) => {
const client = new Auth0Cordova(auth0Config);
const options = {
scope: 'openid profile offline_access'
};
client.authorize(options, (err, authResult) => {
if(err) {
throw err;
}
this.setIdToken(authResult.idToken);
this.setAccessToken(authResult.accessToken);
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
this.setStorageVariable('expires_at', expiresAt);
this.auth0.client.userInfo(this.accessToken, (err, profile) => {
if(err) {
throw err;
}
profile.user_metadata = profile.user_metadata || {};
this.setStorageVariable('profile', profile);
this.zone.run(() => {
this.user = profile;
resolve(profile);
}); // end zone run
}); // end userInfo
}); // end authorize
}); // end Promise
} // end login
(Let me know in comments if there could be a better practice)
See:
How to wait for a function to finish its execution in angular 2.?
javascript, promises, how to access variable this inside a then scope
Update you should be placing the redirection on success of authentication
public login () {
this.authService.login();
///////////////// remove it
}
Place it in the Authservice login() method
login(){
this.redirectAfterLogin ()
}
Or return a Boolean variable on from the login method in AuthService
login() :boolean {
//// your code
if(success) return true;
else return false;
}
In your NavService
public login () {
if(this.authService.login()){
this.redirectAfterLogin ();
}

Categories

Resources