Reputation: 5987
I'm working on an android app using NativeScript+AngularJS2+TypeScript. Following their doc - http://docs.nativescript.org/angular/tutorial/ng-chapter-0 .
Got stuck at a point when after successfully login user needs to redirect to List
page. Following their Routing section now - http://docs.nativescript.org/angular/tutorial/ng-chapter-3#35-routing
Did everything according to their doc. Here are my codes -
app.component.ts
import {ListPage} from "./pages/list/list.component";
import {Component} from "@angular/core";
import {RouteConfig} from "@angular/router-deprecated";
import {NS_ROUTER_DIRECTIVES, NS_ROUTER_PROVIDERS} from "nativescript-angular/router";
import {LoginPage} from "./pages/login/login.component";
@Component({
selector: "main",
directives: [NS_ROUTER_DIRECTIVES],
providers: [NS_ROUTER_PROVIDERS],
template: "<page-router-outlet></page-router-outlet>"
})
@RouteConfig([
{ path: "/Login", component: LoginPage, name: "Login", useAsDefault: true },
{ path: "/List", component: ListPage, name: "List" }
])
export class AppComponent {}
user.service.ts
import {Injectable} from "@angular/core";
import {User} from "./user";
import {ConfigService} from "../config";
import firebase = require("nativescript-plugin-firebase");
@Injectable()
export class UserService {
register(user: User, config: ConfigService) {
console.log('Email entered : '+user.email);
console.log('Password entered : '+user.password);
console.log("API url going to use is : "+config.apiUrl);
firebase.init(<any>{
persist: true, // Allow disk persistence. Default false.
url: config.apiUrl
}).then(
function (instance) {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
return firebase.createUser({
email: user.email,
password: user.password
}).then(
function (response) {
console.log(response);
return response;
}
)
}
login(user: User, config: ConfigService) {
firebase.init({
persist: true, // Allow disk persistence. Default false.
url: config.apiUrl
}).then(
function (instance) {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
return firebase.login({
type: firebase.LoginType.PASSWORD,
email: '[email protected]',
password: 'firebase'
}).then(
function (response) {
console.log(response);
return response;
}
)
}
}
login.component.ts
import {Router} from "@angular/router-deprecated";
import {Component} from "@angular/core";
import {User} from "../../shared/user/user";
import {UserService} from "../../shared/user/user.service";
import {ConfigService} from "../../shared/config";
import {HTTP_PROVIDERS} from "@angular/http";
import firebase = require("nativescript-plugin-firebase");
@Component({
selector: "my-app",
providers: [UserService, HTTP_PROVIDERS,ConfigService],
templateUrl: "pages/login/login.html",
styleUrls: ["pages/login/login-common.css", "pages/login/login.css"]
})
export class LoginPage {
user: User;
isLoggingIn = true;
config:any;
constructor(private _router: Router, private _userService: UserService) {
this.user = new User();
this.config = new ConfigService();
}
submit() {
if (this.isLoggingIn) {
this.login();
} else {
this.signUp();
}
}
login() {
var result = this._userService.login(this.user,this.config);
result.then(
function (result) {
console.log("Login Successs");
// the result object has these properties: uid, provider, expiresAtUnixEpochSeconds, profileImageURL, token
var response = JSON.stringify(result);
console.log('Login Response : '+response);
// Route to list page
this._router.navigate(["List"]);
},
function (errorMessage) {
console.log("Login Error");
console.log(errorMessage);
}
);
}
signUp() {
var result = this._userService.register(this.user,this.config);
result.then(
function (result) {
// dialogs.alert({
// title: "User created",
// message: "userid: " + result.key,
// okButtonText: "Nice!"
// })
console.log('User Object Info : '+JSON.stringify(result));
console.log('User Created with user id - '+result.key);
alert("Your account was successfully created.");
this.toggleDisplay();
},
function (errorMessage) {
// dialogs.alert({
// title: "No user created",
// message: errorMessage,
// okButtonText: "OK, got it"
// })
console.log('No user created. Got error message insted - '+errorMessage);
alert("Unfortunately we were unable to create your account.")
}
);
}
toggleDisplay() {
this.isLoggingIn = !this.isLoggingIn;
}
}
Everything workign fine except at the time of executing this._router.navigate(["List"]);
from file login.component.ts
I'm getting following error
JS: EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property '_router' of null
Can't able to understand what exactly the error is.
Regards
Upvotes: 1
Views: 1283
Reputation: 185
Yes you can dynamically bind this
as George Edwards pointed out. Another option is to use arrow functions which would allow you to retain the scope of the caller inside the function so that you won't need to always remember to write var that = this
.
login() {
var result = this._userService.login(this.user,this.config);
result.then(
// Within the arrow function 'this' now refers to the lexical context rather than changing depending upon how the function is called.
(result) => {
console.log("Login Successs");
// the result object has these properties: uid, provider, expiresAtUnixEpochSeconds, profileImageURL, token
var response = JSON.stringify(result);
console.log('Login Response : '+response);
// Route to list page
this._router.navigate(["List"]); //reference _router from the original scope
},
// Arguably clearer
(errorMessage) => {
console.log("Login Error");
console.log(errorMessage);
}
);
}
Upvotes: 2
Reputation: 9229
I expect this issue is to do with context scope issues. I think you should try and capture the scope before you divine into your then's. I usually store this in a variable called that
see below ( and see the comments):
login() {
var result = this._userService.login(this.user,this.config);
var that = this; //store the current context
result.then(
function (result) { //context (this has changed)
console.log("Login Successs");
// the result object has these properties: uid, provider, expiresAtUnixEpochSeconds, profileImageURL, token
var response = JSON.stringify(result);
console.log('Login Response : '+response);
// Route to list page
that._router.navigate(["List"]); //reference _router from the original scope
},
function (errorMessage) {
console.log("Login Error");
console.log(errorMessage);
}
);
}
Upvotes: 7