I have been struggling with this now for a while and tried many solutions.
Inside my subscribe I cant access ChangeDetectorRef or the NgZone to force an update on my scope.
Why doesn't anything work? Is there any other Angular aware way of doing HTTP requests?
The login component
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, NgZone, OnInit} from '@angular/core';
import {LoginService} from './login.service';
import {Observable} from 'rxjs/Observable';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
providers: [LoginService]
})
export class LoginComponent implements OnInit {
zone: NgZone;
username = '';
password = '';
showerror = false;
errormsg = '';
rs = {};
results: any;
constructor(private _loginService: LoginService, private ref: ChangeDetectorRef) {
}
refr = function () {
console.log('refresh');
console.log(this.errormsg); // is empty even after HTTP call
this.ref.markForCheck();
console.log(this.results);
};
login = function () {
console.log(this.username, this.password);
this._loginService.login(this.username, this.password).subscribe(function (data) {
console.log('log me in');
console.log(data); // the correct data is logged here
this.errormsg = 'Invalid Username and Password'; // the text is never updated
this.zone.run(); // zone has no method run
this.ref.markForCheck(); // ref has no method markForCheck
});
// this.results = this._loginService.login(this.username, this.password);
// this.results.subscribe(rs => this.rs = rs);
};
ngOnInit() {
}
}
The login service
import {Injectable} from '@angular/core';
import {CONFIG} from '../config';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
const loginUrl: string = CONFIG.apiserv + 'api.login.php';
@Injectable()
export class LoginService {
private http;
constructor(http: Http) {
this.http = http;
}
login = function (username, password): Observable<Response> {
console.log('login clicked');
let url = new URLSearchParams();
url.append('username', username);
url.append('password', password);
const fullurl = loginUrl + '?' + url.toString();
return this.http.get(fullurl)
.map((response: Response) => response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
};
handleError = function (error: Response) {
console.log(error);
return Observable.throw(error.json().error || 'Server error');
};
}
since you are using this
, you should use arrow function
:
this._loginService.login(this.username, this.password).subscribe(data => {
console.log('log me in');
console.log(data); // the correct data is logged here
this.errormsg = 'Invalid Username and Password'; // the text is never updated
this.zone.run();
this.ref.markForCheck();
});