Error Can not read property 'message' of undefined in Angular 5

1

I have a problem with angle 5. I have found some similar question but I have not managed to solve anything. The thing is that I have an http service that I am consuming from angular with a get request, which returns a Json. What happens to me is that I can not show this information on the screen.

This would be the method that calls the service:

getPosts(): Observable<Post[]>{
  const httpOptions = {
    withCredentials: true 
  };
return this.http.get<Post[]> (url, httpOptions);
}

The Post class:

export class Post {
  constructor(
    public error: string, 
    public mensaje: string,
    public datos: string
  ) {}
}

The method call:

allPosts: Post[] = [];

constructor( private http:HttpClient, private postService: PostService){ 
  this.postService.getPosts().subscribe(posts =>{
    this.allPosts = posts;
    console.log(posts);

  });
} 

Html Code: It is in this part where I have the problem because if in the html I put:

{{allPosts| json}}

All the JSon appears on the screen. But if I try to get the information separately I get a null or an error. I have tried with the following:

<div *ngFor="let posts of allPosts">    
  <h1>{{posts.mensaje}}</h1>
  <p>{{posts.error}}</p>
</div> 

Error:

'Cannot read property 'mensaje' of undefined'

This gives me the error above, but if I add a question mark '?'

{{posts?.mensaje}}

I do not see any error but on the screen I get a null.

I do not know if I'll have explained myself very well, things are that I'm new to this angle and I'm a little lost ...

The Json returns the following:

{"error":"0","mensaje":"","datos":{"versionesOperativas":["1.0","2.0"],"servidores":{"mc18608":"1524343965"}}}
    
asked by Boortx 25.04.2018 в 13:05
source

2 answers

1

The response of your posts is not an array but an object (a single post and not an array of posts).

You can not iterate with a *ngFor on something that is not iterable, and an object by definition is not.

You can check if a variable is an array by doing:

if(posts.constructor === Array) { ... }

And if that is false then put

this.allPosts=[posts];
    
answered by 25.04.2018 в 13:32
0

I think what you need is a pipe in the http call.

I'm not an expert in angular, but I do the services, I always do them the same, and I do not usually have problems. I'll give you an example:

- Service

getPosts(): Observable<Post[]> {

    let posts: Post[] = [];

    const httpOptions = {
        withCredentials: true
    };
    return this.httpClient.get(url, httpOptions).pipe(
        map( postList => {
            for (let i in postList) {
                let post = new Post(postList[i].error, postList[i].mensaje, postList[i].datos);
                posts.push(post);
            }
            return posts;
        })
    );
}

And then you consume it as you had it, I think it should work for you.

Greetings.

    
answered by 25.04.2018 в 13:59