Angular 2 http get observed twice

In Angular 2 v2.0.1, onInit is called twice. (Obviously, I also do something wrong when he calls once, but that is not a problem right now)

Here is my Plunker: http://plnkr.co/edit/SqAiY3j7ZDlFc8q3I212?p=preview

Here's the service code:

import {Injectable} from '@angular/core';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';

@Injectable()
export class DemoService {


  constructor(private http:Http) { }

  // Uses http.get() to load a single JSON file
  getData() {
    return this.http.get('./src/data.json')
      .map((res:Response) => res.json())
      .do(data => console.log(data))
      .subscribe(data => {
        return <PageContent[]>data;
      }, error => console.log("there was an error!"));
  }
}

export class PageContent {
  constructor(public _id: string, 
  public tag: string, 
  public title: string, 
  public body?:string, 
  public image?: string) {}
}

... and a simple component that uses it.

//our root app component
import {Component, NgModule, OnInit } from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { DemoService, PageContent } from './service';
import { HttpModule } from '@angular/http';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
    </div>
    <div *ngFor="let page of pages">
      {{ page.title }}
    </div>
  `
})
export class App implements OnInit {
  name:string;
  pages: PageContent[] = [];

  constructor(private _service: DemoService) {
    this.name = 'Angular2'
    this.loadData();  // <-- this is called once
  }

  ngOnInit() {
    //this.loadData();  // <-- this is called twice 
  }

  loadData(){
    this.pages = this._service.getData();
    console.log(this.pages);
  }
}

@NgModule({
  imports: [ BrowserModule, HttpModule ],
  declarations: [ App ],
  providers: [DemoService],
  bootstrap: [ App ]
})
export class AppModule {}

Disclaimer: it throws an error, but you can see that it is serviced once when the service method is called from the constructor, but it is called twice when it is inside the ngOnInit hook.

My question is: why is it called twice from the OnInit function?

UPDATE: solution from all answers:

This is a new service method:

getData() {
    return this.http.get('./src/data.json')
        .map((res:Response) => res.json() as PageContent[]);
}

... and this is a new component method:

loadData(){
    this._service.getData()
        .subscribe(data => this.pages = data);
}
+4
source share
4

subscribe . , , (, ), . .

:

  ngOnInit() {
    this.loadData();
  }



  loadData(){
    this._service.getData().subscribe(data => this.pages = data);
  }

:

  getData() {
    return this.http.get('./src/data.json')
      .map((res:Response) => res.json());
  }
+4

this._service.getData() , PageContent. loadData :

loadData() {
  this._service.getData().subscribe(data => this.pages = data);
  console.log("Load data !");
}

subscribe getData ( DemoService). , ngOnInit

+1

, (Observable), , .

, ..

, ( ) .

ngOnInit.

, RXJS , , RXJS.

0

ok ... , ...

return subject.asObservable().flatMap((emit: any) => {

  return this.http[method](url, emit, this.options)
    .timeout(Config.http.timeout, new Error('timeout'))
    // emit provides access to the data emitted within the callback
    .map((response: any) => {
      return {emit, response};
    })
    .map(httpResponseMapCallback)
    .catch((err: any) => {
      return Observable.from([err.message || `${err.status} ${err.statusText}`]);
    });
}).publish().refCount();

RXJS, ( subject.next())

0

Source: https://habr.com/ru/post/1663282/