0

I'm trying to iterate my results in my ngFor - it's not so intuitive like Angular 1. I've the following:

search.service.ts

import {Injectable} from 'angular2/core';
import {Http, HTTP_PROVIDERS, Response} from 'angular2/http';
import 'rxjs/add/operator/map';

@Injectable()
export class SearchService {

  constructor( private _http: Http ) {

  }

  DoGeneralSearch(s){   
    return this._http.get('http://localhost:6000/search?q=' + s)
     .map((res:Response) => res.json())
  } 
} 

typeahead.ts

import {Component, Input, OnChanges} from "angular2/core";
import {SearchService} from "../../../services/search.service";

@Component({
  selector: "typeahead",
  providers: [SearchService],
  template : `
    <div>{{searchSvc | async | json}}</div>
    <div id="typeaheadRooms" *ngIf="searchSvc">
      <div class="typeaheadRowRooms" *ngFor="#item of searchSvc?.rooms">
        <div class="typeaheadRoomTitle">{{item.name}}}</div>
      </div>
      <div class="typeaheadRowRooms" *ngFor="#item of searchSvc?.colors">
        <div class="typeaheadRoomTitle">{{item.name}}}</div>
      </div>
`,
})
export class TypeaheadComponent implements OnChanges {

  @Input() txt: string;
  display = false;

  ngOnChanges(changes: {[propName: string]: SimpleChange}) {
    var search = changes['txt'].currentValue;
    if(search.length > 2) {
        this.display = true;
        this.searchSvc = this._searchService.DoGeneralSearch(search);
    }
    else
    {
        this.display = false;
    }
  }

  constructor(private _searchService: SearchService) {}
}

a typical results in json :

{  
"max":20,
"queryString":"chem",
"rooms":[  
  {  
     "name":"Lima"
  },
  {  
     "name":"Delta"
  }
 ],
"colors":[  
  {  
     "name":"Red"
  },
  {  
     "name":"Lime"
  }
 ]

}

What's happening ? Well, {{searchSvc | async | json}} show me results. But the ngFor: No :(

Any clues? thank you in advance !!!

2

1 Answer 1

1

In this case, you need to use this:

<div class="typeaheadRowRooms" *ngFor="#item of searchSvc | async">

and update your service like this:

DoGeneralSearch(s){   
  return this._http.get('http://localhost:6000/search?q=' + s)
     .map((res:Response) => res.json().rooms);
}

Edit

If you want to receive the full object from the observable, I see two ways to do that:

  • Explicit subscribe:

    this._searchService.DoGeneralSearch(search).subscribe(
      (data) => {
        this.searchSvc = data;
      }
    );
    

    and in the template

    <div class="typeaheadRowRooms" *ngFor="#item of searchSvc?.rooms">
    
  • Custom pipe to get the rooms data:

    @Pipe({name: 'field'})
    export class FieldPipe implements PipeTransform {
      transform(value, args:string[]) : any {
        return value[args[0]];
      }
    }
    

    and in the template

    <div class="typeaheadRowRooms" *ngFor="#item of searchSvc | async | field:rooms">
    
Sign up to request clarification or add additional context in comments.

6 Comments

Hi again, Therry ;) Well..I edited the result...it can return rooms or colors in fact. if I set this on the service..I will restrict myself just to grab the rooms array :( Just for curious I set in this fashion to test your async on the ngFor and it's works..but I really need to iterate in different keys....
Almost there ! I just added: import "Pipe, PipeTransform} from "angular2/core" , @ component....pipes: [FieldPipe]....@ pipe(....) , @ export class FieldPipe (....) and this still throw me a No Directive annotation found on TypeaheadComponent - Something missing ?
It seems that a @Component annotation is missing on your TypeaheadComponent component... Could you give me the corresponding code?
sure ! [typeahead]: import {FieldPipe} from '../../_generics/field-pipe.component';______ @Component({ selector: "typeahead", providers: [SearchService], pipes: [FieldPipe]... template : <div class="typeaheadRowRooms" *ngFor="#item of searchSvc | async | field:rooms"><div class="typeaheadRoomTitle">{{item.name}}</div></div> ____ export class TypeaheadComponent (...) this.searchSvc = this._searchService.DoGeneralSearch(search).subscribe( (data) => { this.searchSvc = data; } ); [field-pipe-component] : import and @pipe and expor
I placed your pipe in a different file now...now it's throw me EXCEPTION: Invalid argument '[object Object]' for pipe 'AsyncPipe' in [searchSvc | async | field:rooms in TypeaheadComponent@15:43]
|

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.