Amanda_Panda
Amanda_Panda

Reputation: 1186

Angular map function is returning "undefined is not a function"

I'm following this tutorial https://www.barbarianmeetscoding.com/blog/2016/04/02/getting-started-with-angular-2-step-by-step-6-consuming-real-data-with-http/, with Angular2 and VS Code. I created a db.json server to test an api with, with the test data looking like

{
"articles": [{
            "id": 1,
            "name": "Wand of Lightning",
            "description": "A powerful wand of ligthning.",
            "price": 50,
            "imageUrl": "/assets/images/wand.png",
            "specs": [{
                "name": "weight",
                "value": 10
            }, {
                "name": "height",
                "value": 22
            }, {
                "name": "material",
                "value": "wood"
            }],
            "reviews": [{
                "author": "Jaime",
                "title": "I loved it!",
                "content": "I loved the wand of ligthning! I usually use it to charge my laptop batteries!",
                "rating": 5
            }, {
                "author": "John Doe",
                "title": "Underwhelming",
                "content": "I didn't like it at all...",
                "rating": 1
            }]
        }, {
            "id": 2,
            "name": "Staff of Fire",
            "description": "A powerful staff of fire.",
            "price": 150,
            "imageUrl": "/assets/images/staff-of-fire.png",
            "specs": [{
                "name": "weight",
                "value": 10
            }, {
                "name": "height",
                "value": 22
            }, {
                "name": "material",
                "value": "wood and alabaster"
            }],
            "reviews": [{
                "author": "Jaime",
                "title": "I loved it!",
                "content": "I loved the wand of ligthning! I usually use it to charge my laptop batteries!",
                "rating": 5
            }, {
                "author": "John Doe",
                "title": "Underwhelming",
                "content": "I didn't like it at all...",
                "rating": 1
            }]
        }

Now if I try to adapt my code to the sample, I get

undefined is not a function

Here's items.component.ts

import { Component, OnInit } from '@angular/core';
import {ItemsService} from '../items.service';
import {Item} from '../item';
@Component({
  selector: 'app-items',
  templateUrl: './items.component.html',
  styleUrls: ['./items.component.css']
})
export class ItemsComponent implements OnInit {
 items: Item[] = [];
 errorMessage: string = '';
isLoading: boolean = true;
  constructor(private itemsService: ItemsService) { }

  ngOnInit() {
    this.itemsService
    .getAll().
    subscribe(
      p => this.items =p,
      e => this.errorMessage = e,
      /* onCompleted */ () => this.isLoading = false

    )
  }

}

items.service.ts

import { Injectable } from '@angular/core';

import { Http, Response, RequestOptions, Headers } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

import {Item} from './item';
@Injectable()
export class ItemsService {
  private baseUrl: string ='http://localhost:3000';
  constructor(private http: Http) { 

  }
  getAll(): Observable<Item[]>{
    let items = this.http
      .get(`${this.baseUrl}/articles`, { headers: this.getHeaders()})
      .map(this.mapItems)
      .catch(this.handleError);
      return items;
  }
  private getHeaders(){
    let headers = new Headers();
    headers.append('Accept', 'application/json');
    return headers;
  }
  mapItems(response:Response): Item[]{

      return response.json().map(this.toItem)
}

 toItem(r:any): Item{
  let result = <Item>({
    id: r.id,
    name: r.name,
    description: r.description,
    price: r.price,
    imageUrl: r.imageUrl,
  });
  console.log('Parsed item:', result);
  return result;
}





// this could also be a private method of the component class
 handleError (error: any) {
  // log error
  // could be something more sofisticated
  let errorMsg = error.message || `Yikes! There was a problem with our hyperdrive device and we couldn't retrieve your data!`
  console.error(errorMsg);

  // throw an application level error
  return Observable.throw(errorMsg);
}









}

Note: making

return response.json().map(this.toItem)

Into

return response.json()

works. But I would like to get map working.

EDIT: Screenshot

enter image description here

Upvotes: 0

Views: 2905

Answers (2)

Rahul Singh
Rahul Singh

Reputation: 341

this will solve your issue -

getAll(): Observable<Item[]> {
    const items = this.http
      .get(`${this.baseUrl}/articles`, {headers: this.getHeaders()})
      .map((response: Response) => this.mapItems(response.json()))
      .catch(this.handleError);
    return items;
  }

mapItems(data: Array<any>): Item[] {
    return data.map(item => this.toItem(item));
  }

Upvotes: 1

CozyAzure
CozyAzure

Reputation: 8478

I think what you want to map (Array.prototype.map) is the articles in your response object, and not the object itself. Do this:

mapItems(response:Response): Item[]{
    return response.json().articles.map(this.toItem)
}

Upvotes: 0

Related Questions