2016-05-22 1 views
2

У меня есть сервис. В конструкторе:Потребляйте Json файл из Сервиса в Угловом 2

export class Service { 

    _data: any 

    constructor(private http: Http) { 
    this.http 
     .get('../assets/my_json_file.json') 
     .map(x => x.json()) 
     .subscribe((data) => 
     this._data = data 
    ) 
    console.log(this._data) 
    } 

В console.log возвращается undefined хотя он показывает данные, если console.log перемещается в функцию передается subscribe.

Моя цель состоит в том, чтобы иметь ряд функций getStuff() в службе, вызываемом приложением на ngOnInit со значениями для выпадающего меню и прочего

посещением this, но не помогло выяснить, что пошло не так

+1

Вы не можете использовать его так. * Http * является асинхронным, и вы хотите использовать его синхронно. У вас могут быть * функции getStuff * в службе, но вам нужно начать вызов этих функций, когда данные готовы, это можно сделать только при наличии другого абонента в компоненте приложения. Так что неважно, что это * json *, данные извлекаются с тем же * http *, что и с сервера. – tibbus

ответ

5

this.http.get('../assets/my_json_file.json') - это асинхронный, что означает, что вызов для сервера запланирован для последующего выполнения, и когда ответ от сервера поступит в конце, обратный вызов, переданный в .subscribe(...), будет вызван с ответом. «запланировано» означает, что задача будет добавлена ​​в очередь событий для последующего выполнения, когда выполняются ранее запланированные задачи.

После завершения http.get(...) звонок console.log(this._data) будет выполнен. Это до того, как звонок на сервер даже начался.

Звонок http.get(...) также запланирован только в том случае, если наблюдаемый, возвращенный http.get(...), подписан, поскольку наблюдаемые являются ленивыми.

Использование map(...) вместо subscribe(...), возвращает Observable вместо Subscription, который позволяет пользователю вашей службы в цепи его собственного кода к событиям реагирования.

@Injectable() 
export class Service { 

    _data: any 

    constructor(private http: Http) {} 

    getData() { 
    this.http 
     .get('../assets/my_json_file.json') 
     .map(x => x.json()) 
     .map((data) => 
     this._data = data 
    ) 
    console.log(this._data) 
    } 
} 

В качестве компонента вы можете использовать его как

export class MyComponent { 
    constructor(service:Service) { 
    // `subscribe` actually initiates the call to the server 
    service.getData().subscribe(result => console.log(result)); 
    } 
} 

Смотрите также What is the correct way to share the result of an Angular 2 Http network call in RxJs 5?

Таким образом, вы уже можете инициировать вызов к серверу, когда услуга инстанцированный, а не только после того, компонент, который использует подписчиков услуг.

Смежные вопросы