Brian
Brian

Reputation: 85

Angular 7 - HttpClient "Property 'success' does not exist on type Object"

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

Answers (3)

Mishan Madhupa
Mishan Madhupa

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

joh04667
joh04667

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

muradm
muradm

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

Related Questions