Angular2 delay for update

I noticed strange behavior with my components using Angular 2. My views take a few seconds to update when my component changes the model included as my suppliers. Even if the data from the API is single data.

For instance:

I have as my provider a model called UserModel Inside my component, I get data from the API, and then update this model, which is also inside my view. After receiving a response from the server, it still takes a few seconds to update my view, and sometimes it does not update immediately after I click on any text controller on the same page, and then my view is updated after any text is received focus.

Has anyone already seen this? What can i do wrong?

Map component

public createCard(model:CardModel):Promise<any>{ var context = this; return new Promise((resolve, reject) => { this.stripe.createToken(model) .then(function(token){ model.token = token; context.saveCard("./card", model, true) .then(data => resolve(data)) .catch(error => reject(error)); }) .catch(error => reject(error)); }); 

Stripe Service

 public createToken(model:CardModel):Promise<any>{ //I get callback and convert return it as promise return new Promise((resolve, reject) => { //this function is the one from stripe.js, it is not promise this.stripe.card.createToken(model, function(status, response){ if(status == 200){ resolve(response.id); }else{ reject(response.error.message); } }); }); } 

If you notice that the createToken function is returned as a callback because it is the Strip.js function, then I will convert it to Promise to return it to createCard. But as soon as all functions are completed, my zone will not be changed. If I remove this.stripe.card.createToken and return to a simple solution () using a timeout, it works fine. Therefore, I believe the problem is when the async function returns a callback inside Promise. But I have no idea how to deal with this.

+5
source share
1 answer

It seems you are using a third-party library that does not work with Angular 2. I had the same problem with StripeJS. The problem is with Angular Zone.js and Lifecycle - it is very similar to the problem with the wrong digest cycle in Angular 1. Angular contains detailed documentation for the solution here: https://angular.io/api/core/ChangeDetectorRef#example-live -demo

To solve this problem, you must implement your life cycle and add your third-party library to change detection. My implementation for StripeJS (also remember to destroy setInterval with clearInterval:

 import { Component, Input, Output, EventEmitter, AfterContentInit, ChangeDetectorRef, ChangeDetectionStrategy, ViewContainerRef, OnDestroy } from '@angular/core'; @Component({ selector: 'v-payment-form', // <payment-form></payment-form> changeDetection: ChangeDetectionStrategy.OnPush, templateUrl: './payment-form.component.html' }) export class PaymentFormComponent implements AfterContentInit, OnDestroy { checker: any; constructor(private changeDetectorRef: ChangeDetectorRef) { this.checker = setInterval(() => { // the following is required, otherwise the view will not be updated this.changeDetectorRef.markForCheck(); }, 75); } addPaymentMethod() { Stripe.card.createToken(cardDetails) this.changeDetectorRef.detectChanges() } ngAfterContentInit() { // ..load stripe js here - I use scriptjs } ngOnDestroy(): void { clearInterval(this.checker) } } 
0
source

All Articles