Search code examples
javascriptarraysangularhttp-getangular-http

save results in an array in Angular 4 after http.get()


I retrieve from an api with http.get() an array of objects. Each of item has only one property inside it: "number". I want that property to be stored in an array in my app.component. I will then use that array as data for a chart using chart.js, which for now works fine. It's more than a day that I am trying but can't figure out how to do it. Can you tell me please?

data that I get from api

app.component.ts

import { Component } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/Rx';

import * as moment from 'moment';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  nrs: any;
  count: any;
  public listNrs: Array<number> = [];

  private apiAllUrl: string = 'http://localhost:3000/api/all';
  private apiCountUrl: string = 'http://localhost:3000/api/count';
  //private apiBothUrl: string = 'http://localhost:3000/api/both';

  constructor(private http:Http) { 
    let now = moment.locale("it");
  }

  ngOnInit() {
    this.getAllNrs();
    this.getCountNrs();
    this.getDataNumbers();
    //this.getCount();
    //this.loadData();
  }

  getAllNrs() {
    this.http.get(this.apiAllUrl)
      .map((res:Response) => res.json())
      .subscribe(
        data => { this.nrs = data},
        err => console.error(err),
        () => console.log(this.nrs)
      );
  }

  getCountNrs(){
    this.http.get(this.apiCountUrl)
      .map((res:Response) => res.json())
      .subscribe(
        data => { this.count = data},
        err => console.error(err),
        () => console.log(this.count)
      );
  }

  getDataNumbers(){

  }

  //tried using jsonp
  /*loadData() {
    this.jsonp.get(this.apiAllUrl)
        .map(res => res.json())
        .subscribe(data => console.log(data));
  }*/

  /*getCount(){
    this.getAllNrs();
    for(let nr of this.nrs){
      console.log(this.nrs.nr[1]);
    }
  }*/

  newDate(days) {
    return moment().add(days, 'days');
  }

  public lineChartData:Array<any> = [
    {data: [4, 5, 56, -23, 4,], label: 'Indexer meta served links'},
  ];

  public lineChartData1:Array<any> = [
    {data: [-23, 4, 4, 5, 56], label: 'Indexer served links'},
  ];

  public lineChartData2:Array<any> = [
    {data: [4, 5, 4, 56, -23], label: 'Real-Time served links'},
  ];

  public lineChartLabels:Array<any> = ['1 Lug 2017', '2 Lug 2017', '3 Lug 2017', '4 Lug 2017', '5 Lug 2017'];

  public lineChartOptions:any = {
    responsive: true,
    /*
    scales: {
      xAxes: [{
        type: 'time',
        time: {
          displayFormats: {
            'millisecond': 'DD MMM',
            'second': 'DD MMM',
            'minute': 'DD MMM',
            'hour': 'DD MMM',
            'day': 'DD MMM',
            'week': 'DD MMM',
            'month': 'DD MMM',
            'quarter': 'DD MMM',
            'year': 'DD MMM',
          }
        }
      }],
    },
    */
  };

  public lineChartColors:Array<any> = [
    { // grey
      backgroundColor: 'rgba(255,55,55,0.2)',
      borderColor: 'rgba(255,55,55,1)',
      pointBackgroundColor: 'rgba(255,55,55,1)',
      pointBorderColor: '#fff',
      pointHoverBackgroundColor: '#fff',
      pointHoverBorderColor: 'rgba(255,55,55,0.8)'
    },
  ];

  public lineChartLegend:boolean = true;
  public lineChartType:string = 'line';

  // events
  public chartClicked(e:any):void {
    console.log(e);
  }

  public chartHovered(e:any):void {
    console.log(e);
  }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { ChartsModule } from 'ng2-charts/ng2-charts';

/*import { DataService } from './data.service';
import { DataComponent } from './data/data.component';*/

@NgModule({
  declarations: [
    AppComponent,
    /*DataComponent*/,
  ],
  imports: [
    BrowserModule,
    HttpModule,
    ChartsModule
  ],
  providers: [/*DataService*/],
  bootstrap: [AppComponent]
})
export class AppModule { }

getAllNrs() gets an array of objects where each of those has a property named number.

getAllCount() gets an array of objects where each of those has a property named count.

The problem is that even if I try to map it into an array it tells me that this.nrs is undefined and cannot get its length (Err: Cannot read property 'length' of undefined). Do you have any idea why it does so?

If there is anything else you need let me know and I'll provide it. Thanks!


Solution

  • From your comment, you will need to initialize your all your properties in your constructor, else it will get undefined. Typescript cannot magically know the default values of it even if you give it a type.

    export class AppComponent {
        title = 'app';
        nrs: any;
        count: any;
        public listNrs: Array<number> = [];
        constructor(private http: Http) {
            let now = moment.locale("it");
            //initialize your values.
            this.nrs = [];
            this.count = 0;
        }
        //other codes
    }
    

    After that, you can use .map() to return an array of numbers in your getAllNrs()

    getAllNrs() {
        this.http.get(this.apiAllUrl)
            .map((res: Response) => res.json())
            .subscribe(
                data => {
                    this.nrs = data.map(nrObj => nrObj.number)
                },
            );
    }