1

I was trying to create a small example in Angular2. What I am doing is when I click a button, this does a get to public api and show a quotes, but I can't, the value never shows and I got the error

Cannot read property 'quotes' of undefined in [{{quote.contents.quotes.quote}} in App@4:20]

My Component.ts

import {Component, OnInit, Injectable} from 'angular2/core';
import {Http, HTTP_PROVIDERS, URLSearchParams} from 'angular2/http';
import 'rxjs/add/operator/map';

@Component({
  selector: 'app',
  template: `<ul>
                <li (click)='myAlert()'> Helow World</li>
             </ul>
             <div>
              <spam>{{quote.contents.quotes.quote}}</spam>
             </div>`,
  providers: [HTTP_PROVIDERS]
})

export class App {
  public quote: Object;
  public  logError: string;

  constructor(private http: Http){
    this.quote = {};
  }

  myAlert(){
      this.http.get("http://quotes.rest/qod.json").map(res => { return res.json()})
        .subscribe(
          data => this.quote = data,
          err => this.logError(err),
          () => console.log('Random Quote Complete')
      );

  }
}

My boot.ts

import {bootstrap} from 'angular2/platform/browser'
import {App} from './component'
import {HTTP_PROVIDERS} from 'angular2/http';

bootstrap(App, [HTTP_PROVIDERS]).catch(err => console.error(err));

Index.html

<html>
  <head>
    <title>Angular 2 QuickStart</title>


    <!-- 1. Load libraries -->
    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.1/http.js"></script>

    <!-- 2. Configure SystemJS -->
    <script>
    System.config({
      packages: {
        app: {
          format: 'register',
          defaultExtension: 'js'
        }
      }
    });
      System.import('app/boot')
            .then(null, console.error.bind(console));
    </script>

  </head>

  <!-- 3. Display the application -->
  <body>
    <app>Loading...</app>
  </body>

</html>

How Do I get the values from the service's subscribe and put into my template?

3
  • it's probably because of the http call be asynchronous. Angular will evaluate your template and the 1st time it happens it the quote property will be null. Try using the async pipe. angular.io/docs/ts/latest/api/common/AsyncPipe-class.html Commented Jan 31, 2016 at 15:48
  • also, until the http call is actually done the quote field will just be an empty object. When angular evaluates {{quote.contents.quotes.quote}} it will end up with that error. because there's no 'contents' property on that object. Commented Jan 31, 2016 at 15:52
  • @toskv thanks a lot for your help, let me try you suggest and I back. Commented Jan 31, 2016 at 15:53

1 Answer 1

1

When the template is loaded quote.contents is undefined. Also I noticed that quote.contents contains and Array. after that I changed myAlert() method to:

myAlert(){
      this.http.get("http://quotes.rest/qod.json").map(res => { return res.json()})
        .subscribe(
          data => { this.quote = data.contents.quotes[0].quote; this.author = data.contents.quotes[0].author;},
          err => this.logError(err),
          () => console.log('Random Quote Complete')
      );
  }

And the component to:

@Component({
  selector: 'app',
  template: `<ul>
                <li (click)='myAlert()'> Helow World</li>
             </ul>
             <div>
              <spam>{{quote}}</spam>
              <br>
              <spam>{{author}}</spam>
             </div>`,
  providers: [HTTP_PROVIDERS]
})

And now works.

Note: I don't have a lot skills with Typescript and Angular2 maybe there is another way.

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

4 Comments

self answer good job !! but you don't need to provide HTTP_PROVIDERS as provider while you had already provide same at the time of Bootstrap. secondly yes if {{quote.contents.quotes.quote}} is null first time it may throws error but there is one alternate for the same you have to put ? sign in the expression like this {{abc?}} that mean if abc is null it will not throw any error. hope it will help you for next time !!
@PardeepJain Thanks for the tip. But is rarely that ? or elvis operator does not work to object with array look (that)[github.com/angular/angular/issues/6798]
seems your suggested link is expired check it again !
@PardeepJain you are welcome, I wrote this issuses yestarday, because the suggest works, without array. Thanks for your help.

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.