1

I'm having a bit of a trouble right now in my Angular2 app. I've retrieved multiple objects from my service, thus i want to store each of them to their own class.

I know how to put an object to a class, however how to work it out if there are multiple objects?

My object

[
  {
    "_key": "2343200",
    "_id": "test/2343200",
    "_rev": "_U9JHQXa---",
    "age": 10,
    "name": "Soy"
  },
  {
    "_key": "2342008",
    "_id": "test/2342008",
    "_rev": "_U9JGn0----",
    "age": 20,
    "name": "John"
  },
  {
    "_key": "2342955",
    "_id": "test/2342955",
    "_rev": "_U9JG46u---",
    "age": 32,
    "name": "Jane"
  }
]

Below is my class.

UserDetails.ts

export class UserDetails {
    key: string;
    id: string;
    name: string;
    age: number;
}

Using foreach() could be the solution, but how to access each data if i want to manipulate them?

For example, i want to access the class of the second data.

Any kind of help is appreciated! I thank you in advance.

Edited: im using my apiservice to retrieve my datas.

data: any;

this.apiService.getUsers().subscribe(users=> {
            this.data = users;
        })
Paksi Mega Bumi
  • 117
  • 2
  • 9

2 Answers2

3

How about:

let jsonArray: IUserDetails[] = [
    ....
];

interface IUserDetails {
    _key: string;
    _id: string;
    _rev: string;
    name: string;
    age: number;
}

class UserDetails {
    key: string;
    id: string;
    name: string;
    age: number;

    constructor(data: IUserDetails) {
        this.key = data._key;
        this.id = data._id;
        this.name = data.name;
        this.age = data.age;
    }
}

const instances: UserDetails[] = jsonArray.map(obj => new UserDetails(obj));
console.log(instances[1]); // UserDetails {key: "2342008", id: "test/2342008", name: "John", age: 20}

(code in playground)


Edit

Based on your comment and the edit you made to your question, you need to do the same inside the subscribe handler:

data: UserDetails[];

this.apiService.getUsers().subscribe(users => {
    this.data = users.map(obj => new UserDetails(obj));
})
Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299
  • It would be that if i use `.map` or `.subscribe` it gives errors which said **Type 'Observable' is not assignable to type 'UserDetails[]'.** thus another one is that **Property 'includes' is missing in type 'Observable'.** @NitzanTomer – Paksi Mega Bumi May 10 '17 at 16:08
  • So you don't have an array of objects, you have an observable. Your question is misleading. Change your question to reflect your real code – Nitzan Tomer May 10 '17 at 16:19
  • ah yes my bad, im sorry i have caused you trouble. Indeed im using an api service to store these data. – Paksi Mega Bumi May 10 '17 at 16:31
  • Check my revised answer – Nitzan Tomer May 10 '17 at 16:34
  • It gives me `undefined` when i used `console.log(this.instances[0])`. I'll try to solve this problem – Paksi Mega Bumi May 10 '17 at 16:45
  • At what point are you trying this? You can do that **only** after the subscriber handler has been invoked. Have you placed that `console.log` inside the handler? – Nitzan Tomer May 10 '17 at 16:51
  • Hi, sorry for the late reply. Yes i was wrong on the `console.log()` one. My bad. Yes i am aware of that now. Thank you! – Paksi Mega Bumi May 11 '17 at 07:48
3

Use interfaces instead, I see no need for class here :) Whats the difference between "declare class" and "interface" in TypeScript

export interface UserDetails {
    key: string;
    id: string;
    age: number;
    name: string;
}

And when you receive your data, just type it to your interface, in your service you could return an Observable of UserDetails array, and in your component you can have the array of type UserDetails:

data: UserDetails[];

this.apiService.getUsers().subscribe(users=> {
    this.data = users;
})

For example, i want to access the class of the second data. Using foreach() could be the solution, but how to access each data if i want to manipulate them?

Yes you can use forEach if you need to manipulate your data somehow. Do that inside the callback (subscribe), why you need to do that, is because this is asynchronous. More explanation here: How do I return the response from an Observable/http/async call in angular2?

this.apiService.getUsers().subscribe(users=> {
    this.data = users;
    this.data.forEach(user => {
       console.log(user) 
       // do something!
    })
})

Edit:

We got some more information and you need a boolean value to your UserDetails to toggle the status of the user, and you want to send the id and status to the backend when this happens.

So first off, add a boolean to your interface, let's call it "status". So add the following property to status: boolean to your interface. Since you api don't seem to give a status value, let's iterate each item and add that property in the callback:

.subscribe(data => {
  this.data = data;
  this.data.forEach(x => {
    // set initial value to true or false, depending what you want
    x.status = true; 
  });
})

Then iterate the users in your template, here I have done it like the following (shortened code). You need to adjust your code accordingly, I see from picture you're using (or want to use) on/off slider :)

<table>
  <tr *ngFor="let user of data">
    <td>{{user.name}}</td>
    <td>{{user.status}}</td>
    <td><button (click)="toggleStatus(user)">Toggle Status</button></td>
  </tr>
</table>

And then your toggleStatus:

toggleStatus(user: UserDetails) {
  user.status = !user.status

  // modify to your actual code
  this.service.sendUser(user.id, user.status)
    .subscribe(....)   
}

Demo

Community
  • 1
  • 1
AT82
  • 71,416
  • 24
  • 140
  • 167
  • Hi there! Sorry for the late reply, i'll try to solve this matter. – Paksi Mega Bumi May 11 '17 at 07:46
  • What i like to achieve is that i am able to turn off and on the status of the people. You can take a look here [link](http://imgur.com/a/x0q2d) @AJT_82 – Paksi Mega Bumi May 11 '17 at 08:22
  • Well what does this *on/off* mean programatically? Meaning what are turning on and off? – AT82 May 11 '17 at 08:34
  • Oh, and I just realice that you are having two `name` properties in your class/interface, probably a typo? – AT82 May 11 '17 at 08:45
  • Ohh its just a typo. Sorry bout the confusion. Its like turning offline and online kinda thing – Paksi Mega Bumi May 11 '17 at 09:10
  • Well, I still don't understand, what should happen in code when you turn online/offline? – AT82 May 11 '17 at 09:25
  • Hmm, i want to get the id of the person and the boolean behind the off and on, then send it to the database. – Paksi Mega Bumi May 11 '17 at 09:28
  • As a sidenote, the edit I made to my answer... nowhere in your question did you mention about this status on/off thing, so your question was actually answered already before this edit! Please in future mark what you want *in question* or ask separate questions (so that question does not get too broad). So in theory I wouldn't have needed to provide this edit, but I did anyways cuz I'm bored :D :D So please remember this in the future questions! ;) – AT82 May 11 '17 at 10:07
  • Yes i understand, thank you very much! Indeed it is my intention but, i want to try to solve it by myself. However before reaching to that point i was confused about the implementation of how could i achieve that, thats why i asked this question. But thank you for your time on solving my issue! :D i'll see your demo – Paksi Mega Bumi May 11 '17 at 10:34