Reputation: 85
When someone registers, I post the info to my back-end. When successfully registering a user, I get a json response back of {success: true, msg: "User registered"}. My problem is when I try to do an if statement to check if success is set to true.
Here is my code that isn't working:
// Register User
this.apiService.registerUser(user).subscribe(data => {
if(data.success) {
this.flashMessage.show('Registration successful', { cssClass: 'alert-success', timeout: 3200 });
} else {
this.flashMessage.show('Registration failed', { cssClass: 'alert-danger', timeout: 3200 });
}
});
I was able to console.log the response of data, and it returned:
{success: true, msg: "User registered"}
Here is the code from my ApiService:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { User } from '../models/User';
@Injectable({
providedIn: 'root'
})
export class ApiService {
private baseUri: string = 'http://localhost:5000/api';
private headers = new HttpHeaders().set('Content-Type', 'application/json');
constructor(private http: HttpClient) { }
registerUser(user: User) {
return this.http.post(this.baseUri + '/register', user, { headers: this.headers });
}
}
Here is the code from my Register Component:
onRegisterSubmit() {
const user: User = {
firstName: this.firstName,
lastName: this.lastName,
email: this.email,
username: this.username,
password: this.password
};
// Register User
this.apiService.registerUser(user).subscribe(data => {
console.log(data);
});
}
Screenshot of error from ng serve
I'm quite new to working with angular let alone a back-end, so if you could explain why this error was occurring it would be greatly appreciated.
Please let me know if you need any more information.
Upvotes: 7
Views: 21935
Reputation: 439
Property 'success' does not exist on type 'Object'. Create code as:
// Register User
this.apiService.registerUser(user).subscribe( (data) => {
if(data['success']) {
this.flashMessage.show('Registration successful', { cssClass: 'alert-success', timeout: 3200 });
} else {
this.flashMessage.show('Registration failed', { cssClass: 'alert-danger', timeout: 3200 });
}
});
This change correct my error in Angular ts file.
Upvotes: 4
Reputation: 7427
This is a compiler error, and it's one of the reasons Typescript is awesome!
Your registerUser
method's return type is implicitly an Object
(or {}
) because that's what http.post
is returning. http.post
accepts a generic parameter to define what will be coming back in the response's body
. Without that parameter, it will return type {}
(because, without some sort of definition, JSON is just an unknown Object
)... and a key of success
does not exist on {}
.
Assuming you have a fleshed out response object, just strongly type it:
interface UserPostResponse {
success: boolean
}
...
registerUser(user: User): Observable<UserPostResponse> {
return this.http.post<UserPostResponse>(this.baseUri + '/register', user, { headers: this.headers });
}
Conversely, if you wanted the HttpRequest
itself and not the body, you just have to tell the HttpClient
what part of the response to observe:
registerUser(user: User): Observable<HttpResponse<object>> {
return this.http.post(this.baseUri + '/register', user, { headers: this.headers }, observe: 'response');
}
...and HttpResponse
has a status
, statusText
, body
, etc.
Upvotes: 7
Reputation: 2053
error TS2339: Property 'x' does not exist on type 'Y'
Is compile time error. Angular HttpClient
has various post
function declarations, one of which is:
post<T>(url: string, body: any | null, options?: { ... }): Observable<T>;
Where you can strongly type your type of response. You can introduce response interface and use it like:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User } from '../models/User';
export interface RegisterResponse {
success: boolean;
msg: string;
}
@Injectable({
providedIn: 'root'
})
export class ApiService {
private baseUri: string = 'http://localhost:5000/api';
private headers = new HttpHeaders().set('Content-Type', 'application/json');
constructor(private http: HttpClient) { }
registerUser(user: User): Observable<RegisterResponse> {
return this.http.post<RegisterResponse>(this.baseUri + '/register', user, { headers: this.headers });
}
}
Then you will be type safe from TypeScript compiler perspective.
Otherwise, matched declaration will be:
post(url: string, body: any | null, options?: { ... }): Observable<Object>;
Where Object
has no declared property succuess
, thus will cause that error.
Another way to avoid it is to use as any
or any
, see references below. But normally, you would want TypeScript to track your types.
TypeScript is strongly typed, meaning that it will attempt to make sure that data types your are using are actually correct. So if you are trying to refer to some property which has no known type, it will complain.
You may see also:
And so on to understand the matter.
Upvotes: 1