0

The situation is quite simple - I'm trying to get data from Angular 2 service but target array is always empty. I can see that call to api return data and status 200 and there is no errors in console. Here is my basic service:

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

@Injectable()
export class DataService {
    items = [];
    constructor(private http:Http) {
        this.loadItems();
    }
    loadItems() {
        this.http.get('http://localhost:58928/api/front')
            .map((res: Response) => {
                return res.json();
            })
    }
}

And here is component:

import {Component, Input} from '@angular/core';
import {DataService} from './../../services/data-service';

@Component({
    selector: 'items-list',
    template: `
        <div class="container">
    <div class="items" *ngFor="let item of items|sort:'DESC';let i = index;trackBy: item?.id">
    <a href="/items/{{item.id}}">
        <mdl-card class="demo-card-square" mdl-shadow="2" mdl-card-expand>
        <mdl-card-media>
        <img src="{{item.imgUrl}}" alt="{{item.name}}" style="max-width: 100%">
         </mdl-card-media>
            <mdl-card-title mdl-card-expand>
                <h2 mdl-card-title-text>{{item.name}}</h2>
            </mdl-card-title>
            <mdl-card-supporting-text>
                {{item.shortDescription}}
            </mdl-card-supporting-text>
            <mdl-card-actions mdl-card-border>
                <h6 class='mdl-color-text--grey-600'>От {{item.priceFrom}} рублей.</h6>
            </mdl-card-actions>
        </mdl-card>
        </a>
    </div>
</div>
`,
    styles: [
        `
.container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-around;
    align-content: space-around;
    align-items: stretch;
    width: 100%;
}

.items{
    margin: auto;
    padding-top: 1%;
    padding-bottom: 1%;
}

a {
text-decoration: none;
}

`
    ]
})

export class ItemsList {
    @Input() items = [];
    constructor(private dataService: DataService) {
        this.items = dataService.items;
    }
}

1 Answer 1

4

Basically, when you do this:

@Injectable()
export class DataService {
    items = [];
    constructor(private http:Http) {
        this.loadItems();
    }
    loadItems() {
        this.http.get('http://localhost:58928/api/front')
            .map((res: Response) => {
                return res.json();
            })
    }
}

You call your web API and just map the result, but you don't assign it to anything. Maybe you can modify it like this:

@Injectable()
export class DataService {
    items = [];
    constructor(private http:Http) {
        this.loadItems();
    }
    loadItems() {
        this.http.get('http://localhost:58928/api/front')
            .map((res: Response) => {
                return res.json();
            }).subscribe(data => this.items = data);
    }
}

This time, as soon as the data are there, items will contain them. However, doing this like this is not optimal because it could be that your component loads before the HTTP call is done, and in this case, you'll get an empty array as well. The best would be to either returns the observable (return by map) and make your component subscribed to it or create a new observable that fires when items are initialized.

Here is an example of the first possibility: http://plnkr.co/edit/DD8fqa2dJGksCtOlolO2?p=preview

This approach works, this only thing is that if you call "loadItems" twice, the HTTP call will be done twice. If you want some caching, something more advanced have to be developped with Observables.

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

2 Comments

Thanks for the answer, could you point me please to some informatio regarding using Observables?
I added a plunker to my answer to show you an easy way to do what you want.

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.