0

I am learning to build an angular 6 client to display data from JSON data. I can able to get data from the direct JSON values but don't know how to retrieve the data from a JSON based on an id that references another JSON object. I have tried various ways to achieve this but only results in https://../users/undefined. Here undefined is the Id I am passing from one JSON to another JSON.

This is how the posts JSON looks like,

   [
       {
           "userId": 1,
           "id": 1,
           "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
           "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
       }, ...
   ]

This is the user by id JSON data,

    [
        {
        "id": 1,
        "name": "Leanne Graham",
        "username": "Bret",
        "email": "Sincere@april.biz",
        "phone": "1-770-736-8031 x56442",
        "website": "hildegard.org",
    ]

I want to get the "name": "Leanne Graham" from the user JSON using the "userId": 1 of the posts JSON.

This is what I have in my PostsComponent

    export class PostsComponent implements OnInit {
        posts$: Object;
        user$: Object;
        userId: Number

        constructor(private data: DataService, private route: ActivatedRoute) {
            this.route.params.subscribe(
                params => this.user$ = params.id
            )
        }

        ngOnInit() {
            this.data.getPosts().subscribe(
                data => this.posts$ = data
            );

            this.data.getUser(this.userId).subscribe(
                data => this.user$ = data
            );
        }

User DetailsComponent,

    export class DetailsComponent implements OnInit {
        user$: Object;

        constructor(private data: DataService, private route: ActivatedRoute) {
            this.route.params.subscribe(
                params => this.user$ = params.id
            )
        }

        ngOnInit() {
            this.data.getUser(this.user$).subscribe(
                data=>this.user$ = data
            )
        }

    }

Service,

    getUser(userId){
        return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId);
    }

    getPosts(){
        return this.http.get('https://jsonplaceholder.typicode.com/posts');
    }

What I have,

enter image description here

What I want to achieve,

enter image description here

Thank you.

Community
  • 1
  • 1
Angela Amarapala
  • 1,002
  • 10
  • 26
  • You are assigning `params.id` to `user$`. Are you attempting to assign it to `this.userId`? Because I can't see `this.userId` getting initialised anywhere. – EmandM Sep 12 '18 at 05:31
  • Yes I did that this way. `this.posts$.forEach(ele => { this.userId = ele.id });` but it gives me errors when trying to iterate an Object type. I really do not know how to get this assigned. – Angela Amarapala Sep 12 '18 at 05:34
  • Also, why do you have a $ at the end of your variable names? The convention is to use that for variables of type Observable, but your variables are not observables. And why do you use Object as their type instead of User or Post or Array? You're shooting yourself in the foot. – JB Nizet Sep 12 '18 at 05:54
  • Here I subscribe the data using Observables. I am following a tutorial and they have the variable names with a $. But I want to assign the userId – Angela Amarapala Sep 12 '18 at 05:59
  • Then you should use another tutorial. – JB Nizet Sep 12 '18 at 06:23
  • @JB Nizet Sure. Kindly help me to figure this out. – Angela Amarapala Sep 12 '18 at 06:24
  • I already did. Remove the $ signs, and use appropriate types for your variables. And read the very first comment you got: you never initialize userId anywhere, so it's undefined. – JB Nizet Sep 12 '18 at 06:27
  • @JB Nizet I removed the $'s, it gave me a blank page but earlier I got the data populated. I also initialized the userId this way. `this.posts$.forEach(ele => { this.userId = ele.id });` but it gives me errors when trying to iterate an Object type. I really do not know how to get this initialized. I am new to angular – Angela Amarapala Sep 12 '18 at 06:36

1 Answers1

1

The problem that I faced here was, I am using a pre-built API and this API returns data as an Object of Objects and not Array of Objects. And that is why I could not assign those Objects to an Array<Post> as mentioned by @JB Nizet.

Using a forEach directly on an Object as shown below gives the error Property 'forEach' does not exist on type 'Object'.

    this.posts.forEach(key => {
      this.data.getUser(this.posts[key].userId).subscribe(
        data => {
          this.user = data;
        }
      );
    });

You have to iterate using the keys of the Object and not the Object itself. Then assign the property that you want with a newly created property in the same Object. why I have not created a new string[] variable to assign the list of new property is that JavaScript supports creating properties dynamically on objects (Here is a link with a detailed discussion) and also to avoid unnecessary memory usage. Here is how you can iterate the Object.

    Object.keys(this.posts).forEach(key => {
      this.data.getUser(this.posts[key].userId).subscribe(
        data => {
          this.posts[key].name = data["name"];
        }
      );
    }); 

Now you can iterate the Object in the template and provide the newly created property.

    <li *ngFor="let post of posts">
        <h2>{{post.title}}</h2>
        <p>- {{post.name}} </p>
    </li>

Your result will look something like this

enter image description here

Thank you @EmandM and @JB Nizet for giving me a helping hand.

Angela Amarapala
  • 1,002
  • 10
  • 26