The console is displaying an undefined error for _co.photo, but the code is functioning properly without any issues

I am facing an issue with an Angular component.

When I create my component with a selector, it functions as expected: it executes the httpget and renders a photo with a title. However, I am receiving two errors in the console:

ERROR TypeError: "_co.photo is undefined"
    View_PhotoHolderComponent_0 PhotoHolderComponent.html:2

and

ERROR CONTEXT 
...
PhotoHolderComponent.html:2:8
    View_PhotoHolderComponent_0 PhotoHolderComponent.html:2

In my HTML, I have:

    <div class="photo-holder">
    <h2>{{photo.title}}</h2>
    <img src="{{photo.url}}">
    </div>

and in my TypeScript file:

import { Component, OnInit } from '@angular/core';
import { Photo } from './photo'
import { PhotoDeliveryService } from '../photo-delivery-service.service'

@Component({
  selector: 'app-photo-holder',
  templateUrl: './photo-holder.component.html',
  styleUrls: ['./photo-holder.component.css']
})
export class PhotoHolderComponent implements OnInit {

  photo:Photo
  constructor( private photoService : PhotoDeliveryService) {
  }

  ngOnInit() {
    this.photoService.getRandomPhoto().subscribe((data: Photo) => this.photo = {...data})
  }

}

and in the service file :

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Photo } from './photo-holder/photo'

@Injectable({
  providedIn: 'root'
})
export class PhotoDeliveryService {
  value : Number
  url : string

  constructor(private http: HttpClient) { 
    this.url = "https://jsonplaceholder.typicode.com/photos/";
    this.value = Math.floor(Math.random() * 10) + 1; 
  }

  getRandomPhoto()  {
     return this.http.get<Photo>(this.getUrl())
  }

  getUrl(){
    return this.url + this.value;
  }

}

I suspect that this issue may be due to binding properties before the query results are returned. How can I resolve this problem? Is there a way to wait for the query to finish, or is there another type of issue at play here?

Answer №1

The reason for the error you are experiencing is due to the fact that the template bindings are resolved before your service can resolve, resulting in the photo object being undefined at that time.

To address this issue, one approach is to initialize the photo object and then use ChangeDetectorRef to detect changes and reflect the value returned by the service.

photo:Photo = {
    title:'',
    url:''
};
constructor( private photoService : PhotoserviceService, private cdr:ChangeDetectorRef) {
}

ngOnInit() {
    this.photoService.getRandomPhoto().subscribe((data: Photo) => {
        this.photo =  data;
        this.cdr.detectChanges();
    });
}

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

Navigate to all hyperlinks in browser without the use of jQuery - specifically for Firefox OS

I stumbled upon this interesting solution on a programming forum. I'm curious, how does this code work without relying on jquery? $('a[href^=http]').click(function(e){ e.preventDefault(); var activity = new MozActivity({ name: ...

Converting JSON-style data into a string with the power of node mysql

Just a quick note - I'm a total newbie in the world of web development, so I might be missing an obvious solution here. My challenge is to insert a dataset into a MySQL database using nodejs/expressjs/mysql. I've managed to establish a connecti ...

Emphasize x-axis heading in a Highcharts graph

In my Highcharts bar graph, I am looking for a way to dynamically highlight the x-axis label of a specific bar based on an external event trigger. This event is not a standard click interaction within the Highcharts graph. Currently, I have been able to r ...

What is the best way to display a nested JSON object structure?

{ "Title": "Jurassic Park", "Year": "1993", "Rated": "PG-13", "Released": "11 Jun 1993", "Runtime": "127 min", "Genre": "Action, Adventure, Sci-Fi", "Director": "Steven Spielberg", "Writer": "Michael Crichton, David Koepp", "Actors": "Sam ...

Tips on tallying the frequency of items in a state array

I'm currently working on an application in which clicking a button adds the item's value to the state. The button is clickable multiple times, allowing the same item to be added multiple times in the state array. My current code snippet: export ...

A guide on setting up dual observables in Angular 2

Currently, I am implementing Observable in angular 2 with rxjs. As part of my demonstration, I have utilized fromEvent in a Plunker. Here is the link to my demo: https://plnkr.co/edit/zkgEcdn21CvIKoOycUOy?p=preview In this demo, I have included two input ...

Typescript validation of tokens using Azure functions

Currently working on a website utilizing Azure Static Web App, where the login/registration is managed by Azure B2C. The backend API consists of typescript Azure functions integrated with Azure Static web app. Certain API calls can only be accessed when th ...

Moving information from Ajax to PHP

I'm experiencing an issue with sending data from AJAX to PHP on the same site, "testpage.php". The PHP script doesn't seem to be displaying the data being sent. Using jQuery/Ajax: <script src="http://code.jquery.com/jquery-latest.js" type="t ...

Tips for halting the live graph plotting based on a specific condition with canvas js

I have a piece of code that generates a live graph based on probabilities. I am looking for a way to stop the plotting process as soon as a specific condition is met. <script> window.onload = function () { var dps = []; // dataPoints var c ...

Enabling or disabling a button dynamically in Ionic based on a conditional statement

I am looking to dynamically enable or disable buttons based on specific conditions. The data is retrieved from Firebase, and depending on the data, I will either enable or disable the button. For example, if a user passes the First Quiz, I want to enable ...

What method is best for deleting an item from the database in HTML structure - POST, GET, or XHR action?

I have a webpage that displays content in a table format and allows users to delete a specific row by clicking on it. The structure of my rows is as follows: foreach ($rewards as $reward) { echo '<tr id="' . $reward[&apos ...

Progress Bar Countdown Timer

I have made some progress on my project so far: http://jsfiddle.net/BgEtE/ My goal is to achieve a design similar to this: I am in need of a progress bar like the one displayed on that site, as well as the ability to show the days remaining. Additionally ...

What is the best way to assign a distinct index value to each object in an array

When I use the function below to add an index to each array object, all IDs end up with the same value when I check console.log: var foo = [...this.props.articleList]; foo.forEach(function(row, index) { row.id = index+1; }); console.log(foo); My des ...

What is the best way to obtain user-inputted data from a dynamic input table with dynamically added rows?

I am struggling to fetch the user-entered data from a dynamic inputs table. Each time a new row is added dynamically to the table, I have to create a new array in the component.ts file to retrieve the data using Two-way data binding. Below is the HTML cod ...

Placing a group of input fields and a button based on the data-id attribute of the element

I have a form that appears when a button is clicked, and the save button saves input values into an object. Is there a more efficient way to write this function if I need to create 9 more buttons with different data-id attributes (e.g. data-id="2" and so ...

"Using only JavaScript to target and manipulate child elements within the

I'm currently transitioning from using jQuery to pure JavaScript, and I've just started but am encountering difficulties. Specifically, I am unsure how to select child elements in the DOM. <div class="row-button"> <input type="submi ...

What is the best way to add a class to the initial HTML element in my specific scenario?

Currently utilizing the angular framework in my application. Desire to assign a specific class to only the initial element within my ng-repeat iteration. <div class='initialOnly' ng-repeat = 'task in tasks'>{{task.chore}}</di ...

Tips for enabling multiple v-list-group components to remain open simultaneously (bypassing the default Vue behavior)

Currently, I am facing an issue with Vue's default behavior where only one v-list-group can be open at a time. I am using Vuetify 2.6 and have attempted to use the multiple prop without success. Additionally, individually assigning the :value prop to ...

What causes the variable to be invisible in the imported file?

Within the main.js file, there is a specific code snippet: var test_mysql = require('./test_mysql.js') ... //additional code before(function(){ test_mysql.preparingDB(test_mysql.SQL_query.clear_data); // or test_mysql.preparingDB(SQL ...

Creating a hierarchical JSON format for a nested commenting system

I have a JSON data representing a multi-level comment system as shown below: [{ "thread_id": 2710, "parent_id": "", "username": "string", "comment": "string", "postdate": "2017-06-09T07:12:32.000Z", "id": 1 }, { "thread_id": 2710, "parent_ ...