convert returned Observables to custom class array in angular

Viewed 2472

Hello folks I will keep my question very simpler by showing code

  1. I am using Json placeholder site for the fake rest Api
  2. I have a user class Object
  3. I want to convert returned Observable to the custom class object array.
    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import { Users } from './users.model';
    
        @Injectable({
          providedIn: 'root'
        })
        export class UsersService {
        
          private url = "https://jsonplaceholder.typicode.com";
        
          constructor(private http:HttpClient) {
            console.log(this.getUsers());
           }
        
        
          getUsers():Observable<Users[]>{
            return this.http.get<Users[]>(`${this.url}/posts`);
        }
        
        }

The above is my service

    export class Users {
        email:          string;
        id:             number;
        name:           string;
        phone:          string;
        username:       string;
        
    }

above is my class I haven't included all properties

In my typescript file I have code like.

constructor(private _usersService:UsersService) {
    
  }

  ngOnInit(): void {
   
    this._usersService.getUsers().subscribe(data=>this.users=data);

    console.log(this.users);
  }

Now the things I want is

  1. how to convert returned observable in my custom class object?
  2. I don't have all the fields so how is it possible to map only those fields which I want?

Hope my question is clear..!!

2 Answers

so this answer takes advantage of map() which is imported from rxjs.

before subscribing we are going to pipe a map() function into the observable stream and then map() each element from that array into a new object that fits our User interface

then we subscribe and the data we get then will be an array that fits our User interface

ngOnInit(): void {
   
    this._usersService.getUsers()
    .pipe(map(data => {
      return data.map(item => {
        const user: User = {
          name: item.name,
          email: item.email,
        }
        return user
      })
    }))
    .subscribe(data=>this.users=data);

    console.log(this.users);
  }

You can do like below, in the User class have a constructor and return User while mapping

import { Component, VERSION, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

export class User {
    email: string;
    id: number;
    name: string;
    phone: string;
    username: string;

    constructor( user: User ) {
      Object.assign( this, user );
    }
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})

export class AppComponent implements OnInit  {
  name = 'Angular ' + VERSION.major;

  constructor(private http: HttpClient){}

  ngOnInit() {
    this.http.get<User[]>("https://jsonplaceholder.typicode.com/users")
    .pipe(
      map( data => {
        return data.map( ( user ) => {
          return new User( {
            email: user['email'],
            id: user['id'],
            name: user['name'],
            phone: user['phone'],
            username: user['username'],
          } );
        } );
      } ),
    )
    .subscribe( (users : User[]) => console.log(users) );
  }
}

Working stackblitz

Related