1

I'm currently bumbling my way through an Angular 4 project. I've manageed to overcome most errors myself, so far, however I cannot figure out this one.

I am trying to use *ngFor (async) to display a list of Observable objects. However, I get the error "Cannot assign Course[] to Observable< Course[] >", however I feel like my service is returning an Observable< Course[] >.

course-list.component.ts:

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import { CourseCardComponent } from '../course-card/course-card.component';
import { CourseCardService } from '../course-card/course-card.service';
import { CourseCard } from '../course-card/course-card.model';
import { Observable }     from 'rxjs/Observable';

@Component({
  selector: 'app-course-list',
  templateUrl: './course-list.component.html',
  styleUrls: ['./course-list.component.css']
})
export class CourseListComponent implements OnInit {
  courseCards : Observable<CourseCard[]>;
  loaded = false;

  constructor(private http:Http, private coursecardService:CourseCardService) { }

  ngOnInit() {
    this.coursecardService.getCourses()
    .subscribe(
      courses => {
        this.courseCards = courses;
        console.log(this.courseCards);
        this.loaded = true;
      },
      err => {
        console.log("Error", err);
      }
    )
  }
}

course-card.service.ts

import { Injectable }     from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable }     from 'rxjs/Observable';

import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

import { CourseCard } from './course-card.model';

@Injectable()
export class CourseCardService {
    // Returns this JSON data:
    // [{"firstName":"Jane"},{"firstName":"John"}]
    private URL = '/api/getcourses';

    constructor (private http: Http) {}

    getCourses(): Observable<CourseCard[]> {
        return this.http.get(this.URL)
            .map((response) => {
            let data = response.text() ? response.json():[{}];
                if(data) {
                    return data;
                }
            }
        )
        .catch((error:any) => Observable.throw(error.json().error || 'Server error'));
    }
}

And the HTML for the course-list component Courses

<ul>
  <li *ngFor="let course of courses|async">
    <app-course-card [name]='course.name' [wordcount]=0></app-course-card>
  </li>
</ul>

4 Answers 4

5

This part does return an Observable<CourseCard[]>:

this.coursecardService.getCourses()

But then you are manually subscribing to it, and inside of the subscribe, courses is of type CourseCard[]. So when you try to assign this.courseCards = courses;, that's when you're getting the type mismatch.

The async pipe will do the subscription for you, so you can change your code to:

ngOnInit() {
  this.courseCards = this.coursecardService.getCourses();
}
Sign up to request clarification or add additional context in comments.

Comments

0

Nevermind, I read more about the .subscribe method. It returns a subscription object, I just needed to change it to:

ngOnInit() {
    this.courseCards = this.coursecardService.getCourses();
  }

1 Comment

Instead of writing your own answer, you could accept the answer with the exact same piece of code that Nicholas Tower gave you :)
0

Is your list properties name is correct? let course of courses or supposed to be let course of courseCards?

   <ul>
      <li *ngFor="let course of courseCards|async">
        <app-course-card [name]='course.name' [wordcount]=0></app-course-card>
      </li>
    </ul>

1 Comment

Haha good spot, I found that after fixing the subscription problem.
0

Try like this :

getCourses(): Observable<CourseCard[]> {
    return this.http.get(this.URL)
        .map((response) => <CourseCard[]>response.json())
        .catch((error: any) => Observable.throw(error.json().error || 'Server error'));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.