0
votes

Someone provided me with this plunker to accomplish something I need to do. https://plnkr.co/edit/q9olLVsEcGrskv8oQkV7?p=preview

I played around with it and used it on my own mock data which looks like this.

links = [ {
      link  : 'I need to expand my current brand.',
      val   : 'expand'
  }, {
      link  : 'I need to re-create my Brand.',
      val   : 'recreate'
  }, {
      link  : 'I need to build a Brand for my new Business.',
      val   : 'new-business'
  }, {
      link  : 'I need to build a Brand for my new product.',
      val   : 'new-product'
  }, {
      link  : 'I have a technical difficulty that requires an Artist.',
      val   : 'tech-difficulty'
  } ]

works like a charm. However when I connect a variable containing my Firebase data, which looks like this.

"home_intro_links" : {
    "link01" : {
        "link"  : "I need to expand my current brand.",
        "val"   : "expand"
    },
    "link02" : {
        "link"  : "I need to re-create my brand.",
        "val"   : "recreate"
    },
    "link03" : {
        "link"  : "I need to build a brand for my new Business.",
        "val"   : "new-business"
    },
    "link04" : {
        "link"  : "I need to build a brand for my new product.",
        "val"   : "new-product"
    },
    "link05" : {
        "link"  : "I have a technical difficulty that requires an Artist.",
        "val"   : "tech-difficulty"
    }
}

it just flat out won't work no matter what I've tried to do.

Here's how I'm calling the data.

//the service file

import { Injectable }           from '@angular/core';
import { AngularFire,
    FirebaseListObservable,
    FirebaseObjectObservable }  from 'angularfire2';
import { Observable }           from 'rxjs/Rx';
import 'rxjs/add/operator/map';

@Injectable
export class HomeService {
    HomeIntroLinks: FirebaseListObservable<any>;

    constructor(private af: AngularFire) {}

    getHomeIntroLinks(){
        this.HomeIntroLinks = this.af.database.list('/home_intro_links') as FirebaseListObservable<any>
            return this.HomeIntroLinks;
    }
}

//the component

import { Component, OnInit,
    Pipe, PipeTransform }       from '@angular/core';
import { AngularFire,
    FirebaseListObservable,
    FirebaseObjectObservable }  from 'angularfire2';
import { HomeService }          from '../home.service';

@Pipe({name: 'homeIntroPipe'})

export class HomeIntroPipe implements PipeTransform {
    transform(arr: any, linkSize: number) {
        return arr.reduce((prev, cur, index) => (index % linkSize) ?
            prev : prev.concat([arr.slice(index, index + linkSize)]), []);
  }
}

@Component({
    moduleId:     module.id,
    selector:     'home-intro',
    templateUrl:  './home-intro.component.html',
    styleUrls:    ['./home-intro.component.css'],
    providers:    [ HomeService ]
})

export class HomeIntroComponent implements OnInit{
    homeIntroLinks: FirebaseListObservable<any>;

    constructor(private _homeService: HomeService) {}

    ngOnInit() {
        this._homeService.getHomeIntroLinks().subscribe(HomeIntroLinks =>{
            this.homeIntroLinks = HomeIntroLinks;
                //console.log(this.homeIntroLinks);
            });
    }
}

//the html in the template

<div *ngFor="let links of homeIntroLinks" class="row home_link_container justify-content-center">
   <div *ngFor="let link of links" class="col-4">
      <div class="card">
         <p class="home_link" [routerLink]="'/home/'+link.val" routerLinkActivate="active">
            {{link.link}}
         </p>
      </div>
    </div>
</div>

Is it just me and the way I'm doing things?.... or is there something drastically different about calling on a local variable? So far I've tried the json pipe, I've tried adding json.parse() both in the service and in the component, nothing seems to make the data from Firebase behave the same way. If you'd like to know errors I've been encountering with anything in particular let me know so I can go re-try it and see what it throws back. At this point I can't remember all of them of the top of my head lol.

UPDATE for AJT_82

Here's a screenshot of my console

console view

I tired your next solution. The browser said it didn't recognize firebaseObj so I defined it in the class as firebaseObj;... not sure of what else to do with it. Then I got another error with it not recognizing it so I had to add .this to it so now it looks like this in my @OnInit

this.firebaseObj = this._homeService.getHomeIntroLinks()
        this.homeIntroLinks = Object.keys(this.firebaseObj).map(x => this.firebaseObj[x])

now I'm back to the [object object] issue. Here's a screen shot of the console.

screenshot 02

3
thanks for the update, error suggests that that it's not an array that it's trying to iterate, but rather an object perhaps. Could you just console log in the mapping, so we know for sure how the incoming data looks like. .map((res: Response) => { console.log('res', res); }) and post the response in your question. As a comment, in my answer we indeed tried to map the incoming data to an array, but seems to not be working. So print the incoming data, so that it will be easier to find a solution. Thanks :)AJT82
the last picture I posted of the console is the result of doing the .map, no data came.Optiq

3 Answers

0
votes

Your firebase should be sending the data in this format

 [{
  "link01": {
    "link": "I need to expand my current brand.",
    "val": "expand"
  },
  "link02": {
    "link": "I need to re-create my brand.",
    "val": "recreate"
  },
  "link03": {
    "link": "I need to build a brand for my new Business.",
    "val": "new-business"
  },
  "link04": {
    "link": "I need to build a brand for my new product.",
    "val": "new-product"
  },
  "link05": {
    "link": "I have a technical difficulty that requires an Artist.",
    "val": "tech-difficulty"
  }
}]

You can use map operator to convert the returned data as json format in your service as

 getTasks(): Observable<any[]> {
        return this._http.get(this._url)
            .map((response: Response) => <any[]>response.json())
            .do(data => console.log("data we got is " + JSON.stringify(data)))
            .catch(this.handleError);

LIVE DEMO

0
votes

Try this in service:

 getHomeIntroLinks(){
    this.HomeIntroLinks = this.af.database.list('/home_intro_links') 
        return this.HomeIntroLinks;
 }

and in component:

homeIntroLinks; // remove the typing to firebaseobservable (for now)

ngOnInit() {
    this.homeIntroLinks = this._homeService.getHomeIntroLinks()
}

here you would perhaps need to add the async pipe in the template:

*ngFor="let links of homeIntroLinks | async" 



Else, if it happens to be a object that gets returned from your firebase, map the keys and create an array instead:

ngOnInit() {
    firebaseObj = this._homeService.getHomeIntroLinks()
    this.homeIntroLinks = Object.keys(firebaseObj).map(x => firebaseObj[x])  
}

then for app not throwing error because of loading the view before data has arrived it could be wise to wrap everything inside div with: <div *ngIf="homeIntroLinks"> ... </div>

0
votes

You can use the async pipe with an observable.

<div *ngFor="let links of homeIntroLinks | async" class="row home_link_container justify-content-center">
  ...
</div>

Simplified view to see the results:

  <div *ngFor="let links of HomeIntroLinks | async" class="row home_link_container justify-content-center">
    {{links.link}}
  </div>