Angular2 component - function not recognized
I am trying to create a separate component to handle a news feed presentation. It works fine when I have everything in app.component.ts, but when I strip the code from my own component (news-feed.component.ts) it initially displays fine, but when the menu button is clicked (ex:) <button (click)="getNews('the-telegraph')">telegraph</button>
, it does not recognize the getNews function and generates the following error: " EXCEPTION: Error in. / AppComponent class AppComponent - inline template: 4: 12 called: self.context.getNews is not a function .
Note that it successfully runs the getNews () function in the NewsFeedComponent when the site is loaded first.
Here is app.component.ts:
import {Component} from '@angular/core';
import {NewsService} from './news.service';
import {Observable} from 'rxjs/Rx';
import { NewsFeedComponent } from './news-feed.component';
@Component({
selector: 'news-app',
template:`
<h1>News Feed</h1>
<nav>
<button (click)="getNews('bbc-news')">bbc</button>
<button (click)="getNews('the-telegraph')">telegraph</button>
<button (click)="getNews('the-guardian-uk')">guardian</button>
<button (click)="getNews('independent')">independent</button>
<button (click)="getNews('financial-times')">financial times</button>
<button (click)="getNews('the-economist')">the economist</button>
<button (click)="getNews('sky-news')">sky news</button>
<button (click)="getNews('the-new-york-times')">the new york times</button>
</nav>
<news-feed></news-feed>
`,
styleUrls: ['app/app.component.css']
})
export class AppComponent {
}
Here is news-feed.component.ts:
import {Component} from '@angular/core';
import {NewsService} from './news.service';
import {Observable} from 'rxjs/Rx'
@Component({
selector: 'news-feed',
template: `
<ul>
<li *ngFor="let article of news">
hello2
<a href="{{article.url}}" target="_bank"><h2>{{article.title}}</h2></a>
<p>{{article.publishedAt}}</p>
<img src="{{article.urlToImage}}" style="width: 200px;">
<p>{{article.description}}</p>
</li>
</ul>
`
})
export class NewsFeedComponent {
// public news;
constructor(private _newsService: NewsService) { }
ngOnInit() {
this.getNews('bbc-news');
}
getNews(source) {
this._newsService.getNews(source).subscribe(
// the first argument is a function which runs on success
data => {
this.news = data['articles']
},
error => {
//console.error("Error saving food!");
return Observable.throw(error);
}
);
}
}
Here is the app.module.ts:
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import {FormsModule} from '@angular/forms';
import {NewsService} from './news.service'
import { AppComponent } from './app.component';
import { NewsFeedComponent } from './news-feed.component';
@NgModule({
imports: [BrowserModule,HttpModule,FormsModule],
declarations: [
AppComponent,
NewsFeedComponent
],
providers: [NewsService],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
bootstrap: [AppComponent]
})
export class AppModule { }
Sorry for shortening and pasting all the code. I tried to get this to work on Plunker and failed because I was very silly. Any help would be much appreciated.
source to share
As @echonax and @devqon commented on, you are calling getNews
from AppComponent
, which is defined in your child component NewsFeedComponent
. If that's the problem, try moving the function getNews
to the AppComponent.
And, if you just want to call the child component, you can do it this way.
<nav>
<button (click)="newsFeed.getNews('bbc-news')">bbc</button>
// all the same
</nav>
<news-feed #newsFeed></news-feed>
source to share
You shouldn't be calling a function getNews
from your AppComponent
html (as getNews
not available in its context). Most likely you should click a button, you should set some variable like feedType = 'bbc-news'
and pass it as input binding to yours news-feed
.
There it will get the channel type dynamically using the binding @Input
and you can call the method getNews
with the appropriate selectedfeedType
<h1>News Feed</h1>
<nav>
<button (click)="feedType = 'bbc-news'">bbc</button>
<button (click)="feedType = 'the-telegraph'">telegraph</button>
<button (click)="feedType = 'the-guardian-uk'">guardian</button>
<button (click)="feedType = 'independent'">independent</button>
<button (click)="feedType = 'financial-times'">financial times</button>
<button (click)="feedType = 'the-economist'">the economist</button>
<button (click)="feedType = 'sky-news'">sky news</button>
<button (click)="feedType = 'the-new-york-times'">the new york times</button>
</nav>
<news-feed [feedType]="feedType"></news-feed>
Then add the property binding Input
in news-feed
component
@Input() feedType;
constructor(private _newsService: NewsService) { }
//call getNews with selected `feedType`
ngOnInit() {
this.getNews(this.feedType);
}
source to share