Struggling to Retrieve Class-Declared Variable in Angular 2 HTML Template

In this scenario, I intended to use a service for retrieving data but encountered difficulties. As a result, I developed the functionality within my component instead. Despite successfully obtaining the 'photos' variable through an HTTP request, I encountered issues accessing it from the HTML template, which led to the error mentioned below.

import { Component } from '@angular/core';
import {HTTP_PROVIDERS} from '@angular/http';
import {PhotosComponentComponent} from './photos-component/photos-    component.component';
import {PhotosServiceService} from './photos-component/photos-    service.service';
// import {photos} from './photos-component/photo';
import {Observable} from 'rxjs/Rx';
import {Http, Response} from '@angular/http';

@Component({
  moduleId: module.id,
  selector: 'ang2demo-app',
  templateUrl: 'ang2demo.component.html',
  styleUrls: ['ang2demo.component.css'],
  providers: [PhotosServiceService, HTTP_PROVIDERS]    
})

export class Ang2demoAppComponent {

  title = 'ang2demo works!';

  constructor(private http: Http) {}


  private photosUrl = 'https://jsonplaceholder.typicode.com/photos';

  getPhotos(){

   this.http.get(this.photosUrl)
    .map((res:Response, data) => res.json())
    .subscribe(
      data => {
        let photos = data;
        console.log(photos);
        return photos; //The 'photos' variable now holds all retrieved data from the HTTP GET request. However, I am unable to access it from the template as shown below.
      }
    )
  }



  ngOnInit() {
    this.getPhotos()
  }
}

The following snippet illustrates my template code referenced in the templateUrl:

<div ngIf *ngFor="let photo of photos">{{photo.url}}</div>

An error message stating "cannot read url property of undefined" arises. Why does the photos variable prove inaccessible from the template's HTML?

Answer №1

Your current code does not store the photos on the controller instance, preventing them from being accessible in the template.

@Component({
  selector: 'my-app',
  template: `
    <div *ngFor="let photo of photos">{{photo.url}}</div>
  `,
})
export class App {
  photos: any[];
  private photosUrl = 'https://jsonplaceholder.typicode.com/photos';

  constructor(private http: Http) { }

  ngOnInit() {
    this.getPhotos()
  }

  getPhotos() {
    this.http.get(this.photosUrl)
      .map(data => data.json())
      .subscribe(data => {
        this.photos = data;
      });
  }
}

Check out this simple plunker example showcasing the code.

Answer №2

After struggling with this problem, I decided to remove the logic from the component and integrate it into a Service instead. This way, I was able to return a mapped Observable. By importing the Service into my component and referencing it in the ngOnInit function after declaring it in the constructor, I was able to resolve the issue.

Next, I used *ngFor to iterate through the Observable, but encountered some difficulties. It turns out that when iterating an Observable, you need to use the async pipe like so: "let photo of photos | async". Once I made this adjustment, everything worked smoothly.

It seems that calling the .subscribe method on an array creates its own scope, which then replaces the reference to "this".

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Send an object containing client values to the parent component upon initialization in Angular

I am trying to pass a set of values to the parent component when a child component is loaded. However, I seem to be having trouble with this process. Any assistance or guidance on what might be going wrong would be highly appreciated. Here is the "data cl ...

You are unable to access the property outside of the callback function of the XMLHttpRequest

Currently, I am attempting to retrieve data from an XMLHttpRequest's onreadystatechange callback. Logging the data works perfectly fine within the callback function. However, when I try to use this data outside of the callback function with this.proce ...

How does the Angular2-all.umd.js compare to the angular2.js file?

Currently, Angular 2 is in its 13th beta phase. I came across https://code.angularjs.org/2.0.0-beta.13/ and noticed that there are two different versions of Angular2 available: angular2-all.umd.js angular2.js What distinguishes these two versions from ...

Angular 4 issue: Changing the value in the HTML 5 slider does not trigger the onchange/input event

Below is the html 5 slider along with a button <button type="button" class="btn btn-default zhaw-ict-icon zhaw-icon-hinzufugen zoom-in" (click)="zoomIn()"></button> <input class="btn zoom" type="range" min="1" max="300" [value]="currentZoom ...

Troubleshooting problem with Angular 6 build

ERROR in : "let-" is only supported on ng-template elements. (" </thead> <tbody> <template ngFor [ngForOf]="rows" [ERROR ->]let-rowz="$implicit" let-index="index"> <tr *ngIf="!(datePicker.onlyCurrentMonth && ro ...

Guide on merging paths in distinct modules within an Angular project

I am looking to merge two sets of routes from different modules in my application. The first module is located at: ./app-routing.module.ts import {NgModule} from '@angular/core'; import {Routes, RouterModule} from '@angular/router'; i ...

What is the method for deducing the return type based on the parameter type in a generic function?

Check out this code snippet featuring conditional types: class X { public x: number; } class Y { public y: number; } type DataCategory = "x" | "y"; type TData<T extends DataCategory> = T extends "x" ? X : T extends "y" ? Y : ne ...

What is causing my Auth Guard to fail in Angular?

Working with my AuthGuard, I have encountered a perplexing issue. Despite the API Server and Auth Service functioning properly, there seems to be a glitch in the if (this.isValid()) portion. Regardless of the token verification result, users are consistent ...

There is an issue with the Hook call on the component list map in ReactJS

While working on Review components, I encountered an error when trying to use hooks. Here is the issue: I am using YhSection to manage my parallel components and utilizing array map to incorporate them in the layout content. Interestingly, if I use hoo ...

Encountering an issue with PrimeNG's <p-calendar> component: the error message "date

I encountered an issue resulting in the following error message: core.es5.js:1020 ERROR Error: Uncaught (in promise): TypeError: date.getMonth is not a function TypeError: date.getMonth is not a function This error occurs whenever I attempt to implement ...

When passing an object to a function inside a promise.then, Typescript may generate an error indicating that the object could

Snippet of code below is extracted from a request controller function. Goal The aim was to generate various notifications based on the paths that are modified. let farmerToUpdate = await FarmerModel.findById(farmerId) if (!farmerToUpdate) throw new cont ...

Modifying the status of a RadDataForm Switch editor through code

I'm working on a new angular + nativescript project that relies on the RadDataForm plugin to create forms. I have set up a source object to initialize the form editors, which is functioning correctly. One of the editors is a switch element that I want ...

What is the best approach to creating multiple dropdowns in ant-design with unique options for each?

It seems like I may be overlooking a simple solution here. Ant-Design dropdowns utilize an array of ItemProp objects to show the options, but this restricts me to having only one list of options. const choices: MenuProps['items'] = [ { label: ...

When combining React with Typescript, you may encounter errors like: "The type 'never[]' cannot be assigned to the type 'StateProperties | (() => StateProperties)'. Make sure you are passing the correct argument types in

I have been honing my skills in TypeScript lately. I utilized Node Express TypeScript for the backend and React TypeScript for the frontend. My goal was to fetch data from the backend and display it on the browser, but I encountered an error: property &apo ...

Limit a generic type to only accept literal types

Here I have a question that has two parts: I am curious to know if there is a way in TypeScript where it's possible to restrict a generic to be a specific literal type. What I mean is something like function foo<T is a string literal>(...). Th ...

Difficulty encountered in keeping arrays updated when the page refreshes

Currently, I am working on developing a blackjack game using React. However, I am facing challenges when it comes to updating the hands of both the player and dealer either upon page reloads or if the player requests for an additional card ("hit"). While ...

Managing two select fields in a dynamic Angular form - best practices

On my screen, I am dynamically creating elements using a reactive form. Specifically, I am creating cards with two selection fields each: https://i.sstatic.net/WUvQH.png Situation: When I add a card and choose a layout, the options for that specific layo ...

Is there a way to eliminate the initial and final double quotes within Angular 4?

Similar to JavaScript, TypeScript also uses either double quotes (") or single quotes (') to enclose string data. I have data coming from the backend that includes HTML content. Here is an example of my API response: <p>afjhjhfsd</p> Wh ...

What is the best way to calculate the product of decimal numbers within a TypeScript Number variable?

Imagine you have a number, for example 288.65, and you want to multiply it without the decimal point in order to obtain the result of 28865. However, when attempting to achieve this by using console.log(288.65 * 100), the output is not as expected, showin ...

Leverage jsencrypt in Ionic 3

Struggling to hash passwords for login on my Ionic 3 app, I attempted using jsencrypt following a tutorial but encountered issues as I couldn't grasp how it works... Here's what I tried : npm install --save jsencrypt import { Component } from ...