Angular 2 Observable to Observable []

2019-09-12 12:09发布

问题:

Not sure if the title is accurate as not sure of the exact terminology.

Suppose I have some code like the the below.

When I load an individual resource using the first method I can create an instance of a rich model class which wraps/decorates the plain JS object in the function passed to map(...).

How can I achieve same in the second method where the response is an array of Course objects?

@Injectable()
export class CourseService {

  constructor(private restangular: Restangular) {

  }

  public getCourse(id: number): Observable<any> {
    return this.restangular.one("courses", id).get().map(response =>
      new Course(response)
    );
  }

  public getAllCourses(): Observable<any> {
    return this.restangular.all("courses").getList().map(response => {
      //an array of courses
      console.log(response);
    });
  }
}

回答1:

Since the second method receives an array, you can use Array.map() to iterate on the values of the array and convert each value into a Course instance:

public getAllCourses(): Observable<any> {
  return this.restangular.all("courses").getList().map(response => {
    return response.map(courseData => new Course(courseData));
  });
}

This code can be confusing because:

  • The 1st .map() is Observable.map() (from RxJS library).
  • The 2nd .map() is Array.map() (plain JavaScript).

For brevity, you could write the method body on a single line (thus avoiding the inner return):

public getAllCourses(): Observable<any> {
  return this.restangular.all("courses").getList().map(response => response.map(courseData => new Course(courseData)));
}

But it's slightly harder to read. :)



回答2:

What are you thinking about this approach?

@Injectable()
export class CourseService {

  constructor(private restangular: Restangular) {

  }

  public getCourse(id: number): Observable<any> {
    return this.restangular.one("courses", id).get().map(response =>
      new Course(response)
    );
  }

  public getAllCourses(): Observable<any> {
    return this.restangular.all("courses").getList().map(response => {
      //an array of courses
      let courses = [];
      for (let courseData of response) {
        courses.push(new Course(courseData);
      }
      return courses;
    });
  }
}

Does this fit to your problem?



回答3:

You can simply doing it with

public getAllCourses(): Observable<Course[]> {
    return this.restangular.all("courses").getList().map((resp: Response) => resp.json());
}