I am doing authentication in Ionic 3 using API but In the login process, it is showing error: Cannot read property 'json' of null
This is my providers>restapi>restapi.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import {Http, Headers} from '@angular/http';
let apiUrl = 'http://192.168.1.10/honeybee/HoneyApi/';
@Injectable()
export class RestapiProvider {
constructor(public http: HttpClient) {
console.log('Hello RestapiProvider Provider');
}
getUsers(credentials, type) {
return new Promise((resolve, reject) => {
var headers = new Headers();
headers.append('Access-Control-Allow-Origin' , '*');
headers.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
headers.append('Accept','application/json');
headers.append('content-type','application/json');
this.http.post(apiUrl + type, JSON.stringify(credentials), {headers: headers})
.subscribe(res => {
resolve(res.json());
}, (err) => {
reject(err);
});
});
}
}
This is my loginpage.ts
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { RestapiProvider } from '../../providers/restapi/restapi';
import { ListPage } from '../list/list';
@IonicPage()
@Component({
selector: 'page-loginpage',
templateUrl: 'loginpage.html',
})
export class LoginpagePage {
responseData : any;
userData = {"email": "", "password": ""};
constructor(public navCtrl: NavController, public navParams: NavParams,
public restProvider: RestapiProvider) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad LoginpagePage');
}
getloginUsers(){
this.restProvider.getUsers(this.userData,'user_Login').then((result) => {
this.responseData = result;
if(this.responseData.userData){
console.log(this.responseData);
console.log("User Details");
this.navCtrl.push(ListPage);
}
else{
console.log("Incorrect Details"); }
}, (err) => {
// Error log
});
}
}
This is my loginpage.html
<ion-header>
<ion-navbar>
<ion-title>loginpage</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<form (submit)="getloginUsers()">
<ion-list>
<ion-item>
<ion-label fixed>Email</ion-label>
<ion-input type="email" [(ngModel)]="userData.email" name="email"></ion-input>
</ion-item>
<ion-item>
<ion-label fixed>Password</ion-label>
<ion-input type="password" [(ngModel)]="userData.password" name="password"></ion-input>
</ion-item>
<div padding>
<button ion-button color="primary" block>Login</button>
</div>
</ion-list>
</form>
</ion-content>
I am getting a Cannot read property 'json' of null when I click the login button. Any help appreciated in Advance. Please Help.
First:
ngModel work if you addition FormsModule
in config file.
@NgModule({
declarations: [ MyApp ],
imports: [
FormsModule
...
)],
bootstrap: [...],
entryComponents: [ ... ],
providers: []
})
Second:
Send data as JSON format, add Content-Type:
getUsers(credentials, type) {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http
.post(apiUrl + type, JSON.stringify(credentials), {headers: headers})
.map(res => res.json());
}
and call in loginpage
(without Promise)
this.restProvider.getUsers(this.userData,'user_Login')
.subscribe(res => this.responseData = result);
Third:
Back-end must return success value. If your API has error (no valid email, password) return HTTP error to Client.
CORS headers must be implementation on the Server Part.
credentials
or res
? - Konstantin Okhotnickcredentials
can't be null. And res
is may. Because res
is variable from api (let apiUrl = '192.168.1.10/honeybee/HoneyApi/';) - Konstantin Okhotnick
Please change the method like this
getUsers(credentials, type) {
return new Promise((resolve, reject) => {
var headers = new Headers();
headers.append('Access-Control-Allow-Origin' , '*');
headers.append('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT');
headers.append('Accept','application/json');
headers.append('content-type','application/json');
this.http.post(apiUrl + type, JSON.stringify(credentials), {headers: headers})
.subscribe(res => {
resolve(res); ----- Change like this
}, (err) => {
reject(err);
});
});
}
loginpage.ts
file getloginUsers(){
this.restProvider.getUsers(this.userData,'user_Login').then((result) => {
if(result){
this.responseData = result.json();
if(this.responseData.userData){
console.log(this.responseData);
console.log("User Details");
this.navCtrl.push(ListPage);
}
else{
console.log("Incorrect Details"); }
}
}
, (err) => {
// Error log
});
}
Also, wouldn't it be easier to just return observable instead of a promise?
return this.http.post(apiUrl + type, JSON.stringify(credentials), {headers: headers});
The problem is in your restapi.ts constructor, HttpClient causing the issue;
constructor(public http: HttpClient) {
console.log('Hello RestapiProvider Provider');
}
Change that to this,
constructor(public http: Http) {
// console.log('Hello RestapiProvider Provider');
}
You have an error on this part {headers: headers}
here is your error :
Argument of type '{ headers: Headers; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: Ht...'. Types of property 'headers' are incompatible. Type 'Headers' is not assignable to type 'HttpHeaders | { [header: string]: string | string[]; }'. Type 'Headers' is not assignable to type '{ [header: string]: string | string[]; }'. Index signature is missing in type 'Headers'.
Error is pretty clean so does not need any explanation, your code will work without any issue if you do that change. I tested on my local.
res
object has a value of null, doesn't it? Do aconsole.log(res)
to confirm it. - Sébastien