CJNotts
CJNotts

Reputation: 287

Import HTTP array Values from a service into a component using Angular

I'm currently trying to build an app using Angular and I have a service which obtains an Array of Data from an online source. I'd like to make this array usable in other components but I'm unsure how to pass the date to them.

Currently my service code looks like this:

import { Component } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import { Injectable } from '@angular/core';

import { Bundle } from './bundle';

import 'rxjs/add/operator/map';


@Injectable()
export class OrderInfo {

  private apiUrl = 'http://dev.assured.api.appdatasite.com/catalog';
  bundlelist: any = {};
  products: any = {};
  selectedBundle: Bundle;

    constructor(private http: Http){
        this.getBundles();
        this.getProducts();
        this.getData();
    }

    getData() {
        const auth = btoa("usernamevalue:passwordvalue");
        const h = new Headers();
        h.set('Authorization', 'Basic ' + auth);
        return this.http.get(this.apiUrl, {headers: h})
            .map((res: Response) => res.json())
    }

    getBundles() {
        this.getData().subscribe(bdata => {
            this.bundlelist = bdata.data.bundles;
            console.log(this.bundlelist);
        })
    }


    getProducts() {
        this.getData().subscribe(pdata => {
            this.products = pdata.data.products;
            console.log(this.products);
        })
    }

    onSelect(bundledata: Bundle): void {
        this.selectedBundle = bundledata;
    };

}

The arrays that I'm trying to pass through are "bundlelist" and "products". I'm trying to pass the bundle data through to the following component:

import { Component, Input, OnInit } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';

import { Bundle } from './bundle';
import { Peripherals } from './peripherals';
import { OrderInfo } from './order.service';

@Component({
  selector: 'my-order',
  template: `
      <h1>Select Bundle</h1>
      <ul class="bundles">
        <li *ngFor="let bundledata of Bundle"
        [class.selected]="bundledata === selectedBundle"
          (click)="onSelect(bundledata)" >
          <h2>{{bundledata.id}}: {{bundledata.name}}</h2>
          <p>{{bundledata.description}}</p>
        </li>
      </ul>
      <bundle-detail [bundle]="this.selectedBundle"></bundle-detail>      
  `,
  providers: [OrderInfo]
})

export class OrderComponent {
    constructor(private orderInfo: OrderInfo) { }

    Bundle: BundleList[];

    getBundles(): void {
        this.orderInfo.getBundles().then(bundlelist => this.bundlelist = bundlelist);
        console.log('unga')
      }

   ngOnInit(): void {
    this.getBundles);
  }  

}

The array data is arranged as follows:

{
    "data": {
        "adverts": [],
        "bundles": [{
            "id": "1",
            "name": "Bronze Bundle",
            "price": {
                "installation": "99.99",
                "recurring": "23.99"
            },
            "products": ["1", "2", "3", "4", "9", "10", "15", "15"]
        }, {
            "id": "2",
            "name": "Silver Bundle",
            "price": {
                "installation": "99.99",
                "recurring": "23.99"
            },
            "products": ["1", "2", "2", "2", "2", "4", "9", "10", "15", "15"]
        }, {
            "id": "3",
            "name": "Gold Bundle",
            "price": {
                "installation": "99.99",
                "recurring": "25.99"
            },
            "products": ["1", "2", "4", "5", "9", "10", "15", "15"]
        }, {
            "id": "4",
            "name": "Build Your Own Bundle",
            "price": {
                "installation": "49.99",
                "recurring": "9.99"
            },
            "products": ["1", "10"]
        }],
        "products": [{
            "id": "1",
            "name": "Product 1",
            "price": {
                "upfront": null,
                "installation": "0.00",
                "recurring": "0.00"
            }
        },  {
            "id": "3",
            "name": "Product 3",
            "price": {
                "upfront": "132.00",
                "installation": "9.60",
                "recurring": "2.75"
            }
        }, {
            "id": "4",
            "name": "Product 4",
            "price": {
                "upfront": "60.00",
                "installation": "9.60",
                "recurring": "1.25"
            }
        }, {
            "id": "2",
            "name": "Product 2",
            "price": {
                "upfront": "60.00",
                "installation": "9.60",
                "recurring": "1.25"
            }
        },{
            "id": "5",
            "name": "Product 5",
            "price": {
                "upfront": "228.00",
                "installation": "9.60",
                "recurring": "4.75"
            }
        }, {
            "id": "6",
            "name": "Product 6",
            "price": {
                "upfront": "96.00",
                "installation": "9.60",
                "recurring": "2.00"
            }

        }]
    }
}

The Array data is definitely getting through to the service as can be viewed from the console log to the but I cannot get it to display an unordered list of the values in the order component.

If anyone could let me know where I'm going wrong with this then I'd really appreciate it.

Upvotes: 0

Views: 69

Answers (3)

CJNotts
CJNotts

Reputation: 287

Have changed the code slightly based on the answers from YounesM and Abhay. The code to get the array now reads

 getData() {
    if (this.data) {
        return this.data;
    }
    const auth = btoa("[email protected]:password1");
    const h = new Headers();
    h.set('Authorization', 'Basic ' + auth);
    this.data = this.http.get(this.apiUrl, {headers: h})
        .map((res: Response) => res.json())
    return this.data;
}

getBundles() {
    this.bundlelist = [];
    this.getData().subscribe(bdata => {
        for (let key in bdata.data.bundles) {
            this.bundlelist.push(bdata.data.bundles[key]);
        }
        return this.bundlelist;
    });
    return this.bundlelist;
}

and the code to pull it in to the component is:

export class OrderComponent {
    constructor(private orderInfo: OrderInfo) { }

    Bundle: [];

    getBundles(): void {
       this.Bundle = this.orderInfo.getBundles();
    }

   ngOnInit(): void {
    this.getBundles();
  }  

}

Thanks to both of you for your help. This now seems to be working properly

Upvotes: 0

Abhay
Abhay

Reputation: 483

I think one of the ways to do this is as follows -

in OrderInfo - getBundles function I would return observable itself

getBundles() {
        this.getData().map(bdata => {
            console.log(this.bundlelist);
            return bdata.data.bundles;
        })
    }

in OrderComponent - getBundles function -

getBundles(): void {
    this.orderInfo.getBundles().subscribe((bundlelist) => this.Bundle = bundlelist);
    console.log('unga')
}

same with getProducts function.

If you want to serve pre-fetched data, you can save it in the service, check whether that is available and it it is available return Observable out of it.

Hope it helps.

Upvotes: 1

YounesM
YounesM

Reputation: 2317

Assuming there are no syntax errors (because it should have syntax errors if your code is exactly what you posted above)

this.orderInfo.getBundles().then(bundlelist => this.bundlelist = bundlelist);

You are storing the data in this.bundlelist (which you forgot to define?) and in your template :

<li *ngFor="let bundledata of Bundle" ...>

You use Bundle (which is defined)

Your code should either be

//Template
<li *ngFor="let bundledata of Bundle" ...>

//TS
Bundle: BundleList[];

or

//Template
<li *ngFor="let bundledata of bundlelist" ...>

//TS
bundlelist: BundleList[]; 

Upvotes: 1

Related Questions