0

I created angular 4 app with following component as below.

<div></div>
<p>d3 works!</p>
<button (click)="getCommitData()">button1</button>
<label style="display: block">{{data}}</label>

import {Component, OnInit} from '@angular/core';
import {HttpModule, Http} from '@angular/http';
import 'rxjs/add/operator/toPromise';
import * as $ from 'jquery';

@Component({
  selector: 'app-d3',
  templateUrl: './d3.component.html',
  styleUrls: ['./d3.component.css']
})
export class D3Component {
  user: String = 'angular';
  repo: String = 'angular.js';
  data: String;
  error: String;
  url: string;
  constructor(private http: Http) {
    this.url = 'https://api.github.com/repos/' + this.user +
      '/' +
      this.repo +
      '/commits';
  }

  humanReadableDate(d: Date): String {
    return d.getUTCMonth() + 1 + '/' + d.getUTCDate();
  }

  reformatGITResponse(data: String[]): any {
    return data;
  }

  handleError(error: any): Promise<any> {
    console.error('An error occurred', error); // for demo purposes only
    return Promise.reject(error.message || error);
  }

  getCommitData(): Promise<any> {
    return this.http.get(this.url).toPromise()
      .then(response => this.reformatGITResponse(response.json().data))
      .catch(this.handleError);
  }

}

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AngularAppSimple</title>
<base href="/">

<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <app-root></app-root>
    <app-d3></app-d3>
</body>
</html>

But when i call getCommitData() from component.html I'm getting null for both url and http variables in getCommitData method above. But when initiating constructor is being called and the url variable is being set.

How the type script objects get injected ?

Also how shall i display the data returned from getCommitData method above ?

5
  • I would reccomend using ngOnInit to init variables. "this.user" and "this.repo" may not be availabe in the constructor Commented Oct 4, 2017 at 8:47
  • still getting the same error. Commented Oct 4, 2017 at 8:54
  • post your html content Commented Oct 4, 2017 at 8:59
  • added html content. Commented Oct 4, 2017 at 9:04
  • 2
    your code looks fine check it here plnkr.co/edit/bZqa7Y87mFxpTfCWYU9Y?p=preview check your browsers console there may be some errors Commented Oct 4, 2017 at 9:36

1 Answer 1

1

as @mwe pointed out, do it in ngOnInit ro perhaps the constructor, do not call it directrly from html template as the variables may not be resolved.

try something like

constructor(private http: Http) {
    this.url = 'https://api.github.com/repos/' + this.user +
      '/' +
      this.repo +
      '/commits';
      this.getCommitData();
  }

  getCommitData(): Promise<any> {
    return this.http.get(this.url).toPromise()
      .then(response => {
      **this.loading = false;**
      return this.reformatGITResponse(response.json().data)
      })
      .catch(this.handleError);
  }

basically call the rest api, from constructro than wait until it finishes, and mark it with some flag like LOADING. On the template you can display whole page using ngIf=!loading

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

6 Comments

Also as an additional to note that the constructor method will be called once and when the object is create. So the this.getCommitData(); will be called once throughout the entire Angular app cycle. So the best place to place it if you want the this.getCommitData(); to be called each time the component is loaded on screen is in the ngOnInit
On calling getCommitData from onInit and construtor the variables are getting initiated but when clicking on the button <button (click)="this.getCommitData()">button1</button> it still getting url and http as null.
<button (click)="this.getCommitData()"> should be <button (click)="getCommitData()">
@user5500750 really it is the case? I thought that once I let say change view (with routing), the component will get destroyed, thus when I return it will be constructed once again
@pezetem Not always, angular by default uses a component reuse strategy which reuses the components if the current and future routes are the same. For example you have a route /posts/:id with comonent PostComponent and route from /posts/1 to /posts/2 then angular will resuse the PostComponent. But the explanation from user5500750 wasn't right either.
|

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.