Angular 2, Routes and interpolation issues


#1

Hi,

I created a login component (routed to on start, route ‘’) which when complete loads in some data into a service provided at the app level. All fine. Then it routes to the main view (route, "/main’) just fine…except the interpolation will only render when I start pressing buttons … the data is component data and date preloaded in the service class. I added some test data to my class and it to will only show once I interact.

Do I need to do something with Zones?

Templete:



<img *ngIf=“mainDD.myUser” class=“img-fluid center-block timage” [src]=“mainDD.myUser.user_profile.imageurl” data-toggle=“tooltip” data-placement=“left” title="{{mainDD.myUser.user_profile.name}}">

Settings




Hello


{{title}}


My favorite hero is: {{myHero}}



class:

export class MainUI extends MeteorComponent implements OnInit {
title = ‘Tour of Heroes’;
myHero = ‘Windstorm’;

constructor(private mainDD: SSMainDataService, private router:Router, private ngZone: NgZone){
    super();
}

ngOnInit() {

}

}
My configuration:

“dependencies”: {
"@angular/common": “^2.0.0-rc.4”,
"@angular/compiler": “^2.0.0-rc.4”,
"@angular/core": “^2.0.0-rc.4”,
"@angular/platform-browser": “^2.0.0-rc.4”,
"@angular/platform-browser-dynamic": “^2.0.0-rc.4”,
"@angular/router": “^3.0.0-beta.2”,
“angular2-meteor”: “^0.6.0”,
“angular2-meteor-auto-bootstrap”: “^0.5.6”,
“angular2-meteor-polyfills”: “^0.1.1”,
“bootstrap”: “^4.0.0-alpha.2”,
“meteor-node-stubs”: “^0.2.3”,
“reflect-metadata”: “^0.1.3”,
“rxjs”: “^5.0.0-beta.6”,
“zone.js”: “^0.6.6”
}


#2

Yeah, you need. Check Solution for UI not update (have to click somewhere) & router not work.


#3

Thanks, I do use the “true” in a meteorComponent call … the UI updates just fine in original component…until I change routes, which I did in the this.call(…, true); method.

Switches fine, but once the new route component loads… the Interpolation of properties in the new route component do not update.

Is there something I need to update?


#4

Are you using ngrx?

Because I met a problem which is kind of similar.


#5

No. I am not. I really just started…just what I listed. Unless there is some deeper dependencies.


#6

Can you update your question using code block? Because it shows like below and I cannot see you codes now.


#7

How…code block? No idea. Search gives no usable results.


#8

The codes you shared seem having no problem.

What does your logging part of codes look like? Does it look like this?

Meteor.loginWithPassword(email, password, error => {
  if (error) {
    // ...
    return;
  }

  this._ngZone.run(() => this._router.navigate(['/home']));
});

This part, do you mean it will render after pressing ANY button?


#9

Thanks! Really.

It is a SaaS app, with Twitter oAuth login and I use stripe for subscription verification.

Login code…all of it (routing towards very bottom):

/**

  • Created by Greg on 7/11/2016.
    */
    import {Component, OnInit} from ‘@angular/core’;
    import { Meteor } from ‘meteor/meteor’;
    import { MeteorComponent} from ‘angular2-meteor’;
    import { SSMainDataService } from ‘…/main_data.service’;
    import { FormBuilder, ControlGroup, Validators } from ‘@angular/common’;
    import {Companies} from ‘…/…/collections/Companys’;
    import { Router } from ‘@angular/router’;
    declare var Cookie:any;

function emailValidator(control) {
var EMAIL_REGEXP = /^[a-z0-9!#$%&’+/=?^_`{|}~.-]+@a-z0-9?(.a-z0-9?)$/i;

if (!EMAIL_REGEXP.test(control.value)) {
    return {invalidEmail: true};
}

}

//noinspection TypeScriptCheckImport
import template from ‘./login.component.html’;

@Component({
selector: ‘login’,
template,
styleUrls: [‘login.component.css’]
})
export class LoginComponent extends MeteorComponent implements OnInit {

public errMsg:String = '';
needEmail: ReactiveVar<boolean> = new ReactiveVar<boolean>(false);
loggedIn: ReactiveVar<boolean> = new ReactiveVar<boolean>(false);
public emailForm: ControlGroup;

constructor( private mainDD: SSMainDataService, private router: Router ) {
    super();

    this.autorun(()=>{
        this.needEmail.get();
        this.loggedIn.get();
    });
}

ngOnInit() {
    if (Cookie.get('SSLoginSA')){
        console.log("Yes Cookies Set ... Log In...");
        this.loggedIn.set(true);// = true;
        this.login(Cookie.get('SSLoginSA'));
    }
}

twitterLogin(){
    Meteor.loginWithTwitter((err) => {
        if (err) {
            console.log(err);
            this.errMsg = err.toString();
        } else {
            this.loggedIn.set(true);
            this.login(Meteor.userId());
        }
    });
}

login(userId:string){
    this.call('is.valid.user', userId, (err, result)=> {
        if (err) {
            this.loggedIn.set(false);
            this.errMsg = "Weird... try again!"
            return;
        }
        if (!result) {
            this.loggedIn.set(false);
            this.errMsg = "Invalid User... try again!"
            return;
        }

        this.subscribe('myCompany', userId, () => {
            this.mainDD.myCompany = Companies.findOne(); // only one
            if (this.mainDD.myCompany){
                // good
                this.mainDD.loginId = userId;
                Cookie.set('SSLoginSA', userId);
                this.checkEmail(userId);

            } else {
                // not setup YET
                //this.errMsg = "Login in failed, no Company found... try again!";
                this.call('add.company.subscription', userId, "basic_v2", (error, company) => {
                    if (error) {
                        this.errMsg = "Failed to create company and subscription subscription. Error: " + error;
                        this.loggedIn.set(false);
                    } else {
                        this.mainDD.myCompany = company;
                        this.mainDD.loginId = userId;
                        Cookie.set('SSLoginSA', userId);
                        this.checkEmail(userId);
                    }
                }, true);
            }
        }, true);
    }, true);
}

checkEmail(userId:string) {
    console.log('Check to see if the loggedin user has eMail!');
    this.subscribe('myProfile', userId, () => {
        this.mainDD.myUser = Meteor.users.findOne();
       // console.log("myProfile: " + this.mainDD.toString())
        if (this.mainDD.myUser["emails"]){
            // has email
            this.checkSubscription();
        } else {
            this.needEmail.set(true);// = true;
            let fb = new FormBuilder();
            this.emailForm = fb.group({
                "email": ["", Validators.compose([emailValidator])]
            });
        }
    }, true);

}

addemail(myemail: string) {
    if (this.emailForm.valid){
        //console.log("myEmail: " + myemail);
        this.call("add.user.email", this.mainDD.loginId, myemail); // add it
        this.needEmail.set(false);
        this.checkSubscription();
    }

}

checkSubscription() {
    console.log('Check Subscription status!');

    this.call('get.subscription.status', this.mainDD.myCompany.stripe_subscription_id, (error, status) => {
        if (error) {
            this.errMsg = "Failed to validate subscription. Error: "+error;

        } else {
            console.log('Subscription status: ' + status);
            this.errMsg = "Status: " + status + "!";
            this.mainDD.loginSuccess = true;
            if (status == "trialing") {
                this.mainDD.isTrial = true;
            }
            if (status == "trialing" || status == "active") {
                this.router.navigate(['/main']);
            } else {
                //past_due, canceled, or unpaid
                this.mainDD.subscriptionStatus = status;
                this.router.navigate(['/subscribe']);
            }
        }
    }, true);


}

clearError(){
    this.errMsg = "";
}

}


#10

Still an issue. I think this is the same as:

No solution as far as i can tell, except maybe using zones…but this is totally unclear.


#11

Curiouser:

Initially ngOnInit() is not called … on the second route called, it was the first. And yes the problem is on the second route.

I added the ngZone to the constructor…

this.autorun(() => {
this.ngZone.run(() => {
this.profileURL.get();
console.log(this.profileURL.get());
});
});

Then the ngOnInit() was them called automatically. And the Interpolation started ip again.

Perhaps the ngZone used the pollyfill as was discussed in some threads online.