1

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!

2
  • maybe you need to tell us what does getAllNrs() do, what is getCountNrs(), and most importantly, what is your issue? You are blocked at getDataNumbers() or what? Which exactly the data needs to be sorted? Commented Jul 6, 2017 at 8:37
  • @CozyAzure done. It's all at the end of the question. Thanks for your reply and let me know if you need anything else! Commented Jul 6, 2017 at 8:46

2 Answers 2

1

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)
            },
        );
}
Sign up to request clarification or add additional context in comments.

Comments

1

you can use Array.map to convert array of object to array of string( or what ever).

var arrOfObj = [
  {
    number: 100
  },{
    number: 200
  },{
    number: 300
  },{
    number: 400
  },{
    number: 500
  },{
    number: 600
  }
];

var arrOfStr = arrOfObj.map(function(item) {
  return item.number;
});

console.log(arrOfStr);


As I commented, you can add the Array.map part directly into http.get().map but make sure res.json() is actually the object array

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

Plunker demo

5 Comments

thanks for the reply. The program, however, tells me that it Cannot read property 'length' of undefined when I try to map this.nrs into an array. Do you have any idea why it does so?
@GiovanniPecchio the message is clear enough, it says this.nrs is undefined. can you confirm that?
@GiovanniPecchio I mean you have to confirm why this.nrs is undefined. :-) BTW, which http.get is related here? getAllNrs or getCountNrs? you can do the Array.map part at http.get().map directly.
Oh sorry... I need it for both but if you can show me how to do it for one of the two, I'll do it for the other. Thanks and sorry for the dumb answer before
@GiovanniPecchio seems you have got the solution. although it almost same as mine, but it's good to go. good luck.

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.