1

How do I change this function to work with the JSON change described below?

The current function returns an Observable<User[]>, but with the new JSON, the new admin object has been added. The new function should successfully observe both the existing users array and the new admins array.

getData(): Observable<User[]> {
  return this.http
    .get('www.example.com/api/users)
    .map((r: Response) => r.json().assets.users as User[]);
}

JSON returned from /api/users

{
"assets": {
    "users": [
        // user objects
    ]
}

...now returns two arrays, users and admins.

{
"assets": {
    "users": [
        // array of user objects
    ],
    "admins": [
        // array of admin objects
    ]

}

Please assume that my code does have User and Admin classes already created that correctly reflect the properties of the related JSON objects returned.

7
  • 1
    so what do you want? not clear Commented Jul 14, 2017 at 19:39
  • Thank you for the feedback. I added more details to the beginning of the question. Commented Jul 14, 2017 at 19:48
  • new function should successfully observe - by observe do you mean return objects from both arrays? or return two arrays? Commented Jul 14, 2017 at 19:50
  • The 1st one: return objects from both arrays. Commented Jul 14, 2017 at 19:52
  • but this is not how it's working, it returns an array of users, not users objects Commented Jul 14, 2017 at 19:53

2 Answers 2

1

Well, you have a few options how to return the data:

getData(): Observable<User[]> {
  return this.http
    .get('www.example.com/api/users')
    .map((r: Response) => { 
         const assets = r.json().assets;
         return {
             users: assets.users as User[],
             admins: assets.admins as Admin[]
         }
     });
}

Or like this:

getData(): Observable<User[]> {
  return this.http
    .get('www.example.com/api/users')
    .map((r: Response) => { 
         return [
             assets.users as User[],
             assets.admins as Admin[]
         ]
     });
}

Or like this:

getData(): Observable<User[]> {
  return this.http
    .get('www.example.com/api/users')
    .map((r: Response) => { 
         return [
             ...assets.users as User[],
             ...assets.admins as Admin[]
         ]
     });
}
Sign up to request clarification or add additional context in comments.

6 Comments

To explain what's happening here: .map() returns a new array using the values from the array it is attached to. Therefor, in order to return a new array containing both users and admins, a function needs to be used in .map() to transform the response data into the new desired array.
Can I just say this? You two rock! Great answer and wonderful explanation for an RxJS newb. I'm going to work on implementing this now. I hope my edit helped. I tried to follow the guidelines and "show research effort" but I might have gotten lost down the rabbit hole a bit.
@Maximus can you explain the ellipses in "...assets" in your final answer?
@JerryHuckins, sure, this is called spread syntax and is explained here. Consider accepting my answer if it helped. Thanks
@Maximus I accepted your answer. If you found the question useful, please consider upvoting it.
|
1

If you want to return both users and admins in the same array, the following code should do the trick:

getData(): Observable<User[]> {
  return this.http
    .get('www.example.com/api/users)
    .map((r: Response) => {
        var results = r.json();
        return results.assets.users.concat(results.assets.admins);
    }
}

With the following data:

{
"assets": {
    "users": [
        { "name": "bob" }, { "name": "john" }
    ],
    "admins": [
        { "name": "jill" }, { "name": "donald" }
    ]

}

The result would be equal to:

[ { "name": "bob" }, { "name": "john" }, { "name": "jill" }, { "name": "donald" } ]

As explained in my comment for @Maximus answer, .map() is used to transform an array into a new one, which is why you want to feed a function to .map() to tell it what array you are looking for.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.