0

I am trying to retrieve an object from Array by id with the method getItem().

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

import { IItem } from './item';

@Injectable()
export class ItemsService {
  private _itemsUrl = './items.json';

  constructor(private _http:Http){}

  getItems(): Observable<IItem[]> {
    return this._http.get(this._itemsUrl)
    .map((response: Response) => <IItem[]>response.json().itemsData)
  }

  getItem(id:number): Observable<IItem> {
    return this.getItems()
    .map(items => items.find(item => item.id === id));
  }

}

The service is injected into my component.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { ItemsService } from './items.service';
import { IItem } from './item';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  item: IItem;

  constructor(
    private _ItemsService: ItemsService,
    private route: ActivatedRoute
    ) { }

  ngOnInit(): void {

    this._ItemsService.getItems().subscribe(items => console.log(items))

    this.route.params.forEach((params: Params) => {
        let id = +params['id'];
        this._ItemsService.getItem(id).subscribe(item => console.log(item));
    })
   }
}

Exported class IItem:

export class IItem {
    id?: number;
    title?: string;
    titleUrl?: string;
}

items.json:

{
  "itemsData" : [
    {
      "id": 1,
      "title": "Item 1",
      "titleUrl": "item-1"
    },
    {
      "id": 2,
      "title": "Item 2",
      "titleUrl": "item-2"
    },
    {
      "id": 3,
      "title": "Item 3",
      "titleUrl": "item-3"
    }
  ]
}

I test the methods inside my component: ngOnInit(): void {

    this._ItemsService.getItems().subscribe(items => console.log(items)) //Works fine

    this.route.params.forEach((params: Params) => {
        let id = +params['id'];
        this._ItemsService.getItem(id).subscribe(item => console.log(item)); // Undefined
   }

Tried to create a project in editor, but it doesn't work - sorry

Here!

So, how can I retrieve the object by id from Observable with my getItem method?

3
  • You're not importing HttpClientModule in your appModule. See the docs: angular.io/guide/http Commented Oct 24, 2017 at 22:08
  • Http import is really enough, I think, cause my http request works well on getItems() method. Commented Oct 25, 2017 at 10:33
  • Http import is really enough, I think, cause my http request works well on getItems() method. Commented Oct 25, 2017 at 10:33

2 Answers 2

1

There can be several problems:

  getItem(id:number): Observable<IItem> {
    return this.getItems()
    .map(items => items.find(item => item.id === id));
  }
  1. id parameter is NaN
  2. There is no item with this id
  3. item.id is not a number i.e. string

Just add more logs and will see.

Sign up to request clarification or add additional context in comments.

3 Comments

getItems() returns an array of objects. In console I can see my objects, which contain properties "id" with Numbers value, so none of the three suppositions seems to be true
I seriously doubt that, the only reason could be is that condition item.id === id returns false.
You were right. id is NaN in that case, I remade the code using Promises instead of Observables.
0

The problem is coming from your map function

try this :

getItem(id:number): Observable<IItem> {
    return this.getItems()
    .map((response: Response) => <IItem[]>response.json().itemsData.find(item => item.id === id));
}

1 Comment

Terminal throws the error: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'IItem[]' is not a valid type argument because it is not a supertype of candidate 'Response'. Property 'includes' is missing in type 'Response'.

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.