Every time I load the webpage, I'd have to click the logo in-order my data to fully populate the local array in my component. The data fetched is located in a local JSON file. Having to refresh the page every-single-time is fairly unprofessional/annoying.
Using Angular CLI 1.3.2
Here's where my problem lies:
@Injectable()
export class LinksService implements OnInit{
siteFile : IFile[];
constructor(private http: Http) {
this.getJSON().subscribe(data => this.siteFile = data, error =>
console.log(error));
}
public getJSON(): Observable<any> {
return this.http.get('./assets/docs/links.json')
.map((res:any) => res.json());
}
getAllIpageLinks() : IPageLink[]{
var selectedIPageLinks: IPageLink[] = new Array();
var selectedFileLinks : IFile[] = new Array();
selectedFileLinks = this.siteFile;
for (var i=0; i<selectedFileLinks.length; i++)
{
selectedIPageLinks =
selectedIPageLinks.concat(selectedFileLinks[i].files);
}
return selectedIPageLinks.sort(this.sortLinks);
}
Component:
constructor(private elRef: ElementRef, private linksService: LinksService) {
this._file = this.linksService.getAllIpageLinks();
}
Edit The title has to be clicked in order for array of IFile[] to completely render. I've tried setting IFile to an empty array (IFile[] = []) The error goes away, however, it will render empty data.
The problem seems to be in the For loop, it can't recognize .length.
Problem :
The codes are correct but the approach is wrong. Subscribing to an Observable getJSON()
is async task. Before any data is being returned by getJSON()
, you already calls getAllIpageLinks()
and therefore you get null value on very first run. I believe since you have injected the service as singleton in component, the data gets populated in subsequent call( on refresh by clicking logo).
Solution:
getAllIpageLinks
) by using map
operator on observable. Welcome to StackOverflow . Please copy paste your codes in the question instead of giving screenshot of it. I would be able than to give you along the exact codes
Reference Codes : I haven't tested the syntax but should be enough to guide you. 1. Refactor getAllIpageLinks()
as below
public getAllIpageLinks(): Observable<any> {
return this.http.get('./assets/docs/links.json')
.map((res:any) => res.json());
.map(res => {
var selectedIPageLinks: IPageLink[] = new Array();
var selectedFileLinks : IFile[] = new Array();
selectedFileLinks = res;
for (var i=0; i<selectedFileLinks.length; i++)
{
selectedIPageLinks =
selectedIPageLinks.concat(selectedFileLinks[i].files);
}
return selectedIPageLinks.sort(this.sortLinks);
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.