Angular is throwing an error stating that "ctx" is not defined

Struggling with a weather app using the OpenWeatherMap API, I've encountered service blocking issues twice already due to excessive requests. Despite thoroughly checking my code multiple times, I can't pinpoint any specific loop causing server overload. The console error message that follows is: ERROR TypeError: ctx.amindiDGES is undefined.

The error surfaces on several lines in my main.component.html:

MainComponent_Template main.component.html:8
getLocation main.component.ts:39
ngOnInit main.component.ts:27

Here's an excerpt from my today.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';

import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class TodayService {
  url = 'http://api.openweathermap.org/data/2.5/weather';
  apiKey = '***********************';

  constructor(private http: HttpClient) { }

daitriecoordinatebi(lat, lon) {
  let params = new HttpParams()
    .set('lat', lat)
    .set('lon', lon)
    .set('units', 'metric')
    .set('appid', this.apiKey)

  return this.http.get(this.url, { params });

As for my main.component.ts:

import { Component, OnInit } from '@angular/core';
import { TodayService } from './today.service';


@Component({
  selector: 'app-main',
  templateUrl: './main.component.html',
  styleUrls: ['./main.component.scss']
})

export class MainComponent implements OnInit {
  lat;
  lon;
  amindiDGES;
  kvirisdgeToday;
  ikonkaToday;

  
  title = 'Day1';
  today = new Date();

  constructor(private todayService: TodayService) { }

  ngOnInit(): void {

    // Obtain location
    this.getLocation();
    
    this.today = new Date();
    

  }

  getLocation() {
    if ("geolocation" in navigator) {
      navigator.geolocation.watchPosition((success) => {
        this.lat = success.coords.latitude;
        this.lon = success.coords.longitude;

        this.todayService.daitriecoordinatebi(this.lat, this.lon).subscribe(data => {
          this.amindiDGES = data;
        })
      })
    }
  }
  
}

Portion of my main.component.html:

<table>
  <tbody>
    <tr>
      <td><i class="fas fa-wind"></i></td>
      <td>&nbsp;&nbsp;Wind - {{amindiDGES.wind.speed}}</td>
    </tr>
    <tr>
      <td><i class="far fa-eye"></i></td>
      <td>&nbsp;&nbsp;Visibility - {{amindiDGES.visibility}}</td>
    </tr>
    <tr>
      <td><i class="fas fa-tachometer-alt"></i></td>
      <td>&nbsp;&nbsp;Preassure - {{amindiDGES.main.pressure}}</td>
    </tr>
    <tr>
      <td><i class="fas fa-tint"></i></td>
      <td>&nbsp;&nbsp;Humidity - {{amindiDGES.main.humidity}}</td>
    </tr>
  </tbody>
</table>

Despite successfully receiving data from the server and displaying results, the app remains blocked after some usage due to exceeding the allowable request limit of 60 per minute by making over 800 requests. In addition, a consistent console error persists: ERROR TypeError: ctx.amindiDGES is undefined.

One speculation is that the app might attempt to show data prior to complete retrieval from the server, triggering errors in the console and leading to continuous repeated requests until API access is restricted.

Have you encountered similar challenges with data fetching before?

Answer №1

It appears that the function below has some significant issues:

 getLocation() {
    if ("geolocation" in navigator) {
      navigator.geolocation.watchPosition((success) => {
        this.lat = success.coords.latitude;
        this.lon = success.coords.longitude;

        this.todayService.daitriecoordinatebi(this.lat, this.lon).subscribe(data => {
          this.amindiDGES = data;
        })
      })
    }
  }

According to the documentation :

The Geolocation method watchPosition() method is used to register a handler function that will be called automatically each time the position of the device changes.

This means your code will subscribe to the daitriecoordinatebi observable every time the location changes. Therefore, if the location changes three times, you will have three subscriptions and consequently call the API three times...

You do have several options to address this issue.

  1. Utilize toPromise and then await the result
async (success) => {
    this.amindiDGES = await 
          this.todayService.daitriecoordinatebi(this.lat, this.lon).toPromise();
// or use
     await lastValueFrom(this.todayService.daitriecoordinatebi(this.lat, this.lon))
// as toPromise will be deprecated
})
  1. Use the first operator within pipe to automatically destroy the subscription
 this.todayService.daitriecoordinatebi(this.lat, this.lon).pipe(first()).subscribe...
 // or use take(1)
  1. Implement a Subject and a mergeMap operator for a more elegant solution
positionChanged = new Subject();
  getLocation() {
    if ("geolocation" in navigator) {
      navigator.geolocation.watchPosition((success) => {
        this.lat = success.coords.latitude;
        this.lon = success.coords.longitude;
        this.positionChanged.next();        
      })
    }
    this.positionChanged.pipe(
       mergeMap(()=>this.todayService.daitriecoordinatebi(this.lat, this.lon)))
        .subscribe(data => {
          this.amindiDGES = data;
        })
  }

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

What are the drawbacks of starting with Angular CLI?

Contemplating whether to incorporate Angular CLI into my upcoming project has been on my mind. My main motivation for considering it is to bypass the complexities of setting up a new project and instead focus on mastering the new version of Angular while c ...

Tips for mocking the router.navigate function in Jest

As a newcomer to unit testing with Jest in Angular, I find myself facing a challenge when it comes to testing components that utilize the this.router.navigate() method. Previously, I used Jasmine for testing and followed these steps: import { Router } from ...

Setting up React Context API with TypeScript: A Step-by-Step Guide

I recently updated my app.js file to app.tsx for improved functionality. However, I encountered an error with the current value. app.tsx import React, { createContext, useState } from "react"; import SelectPage from "./pages/select/select& ...

Unable to access current props within useEffect block

When I use useEffect with the parameter props.quizStep, my function fn (which is a keydown event listener) is unable to access the current value of props.quizStep. I'm puzzled as to why it's not working properly. Can you help me understand? Bel ...

Configuration error with MultiCapabilities

Encountering an issue while utilizing multiCapabilities with two web browsers (Firefox and Chrome). Below is a snippet from my configuration: exports.config = { allScriptsTimeout: 11000, seleniumAddress: 'http://localhost:4444/wd/hub', b ...

How can I adjust the font size of information retrieved from a JSON file using ng2-smart-table?

I recently tried using the following CSS code: :host /deep/ ng2-smart-table {font-size:22px;} However, despite implementing this code, I have not noticed any change in the font size. ...

What is the best way to display a variable in Angular that contains HTML without the need for an additional container?

Having trouble with this idea: <ng-container [innerHTML]="dataThatContainsHtml"></ng-container> The code that works, but adds an unnecessary html element: <div class="avoid me" [innerHTML]="dataThatContainsHtml"></div> Any sugge ...

The code breaks when the lodash version is updated to 4.17.4

After updating lodash to version 4.17.4, I encountered an error in Typescript that says: TypeError: _.uniqBy is not a function Uncaught TypeError: _.split is not a function The code snippet in question is as follows: import * as _ from 'lodash&apo ...

error TS2339: The attribute 'properties' is not accessible on the class 'TestPage'

Utilizing a typescript abstract class as the base class of my layout component in React has been essential for my project. The implementation of this base class looks something like this: import { IPageLayoutActions, IPageLayoutLocalState, IPageLayoutProp ...

What is the best way to implement an onClick event listener in a TypeScript React application?

Is there a way to properly add an onClick event listener to a div element in my code snippet below? useEffect(() => { if (ref.current === null) { return; } const handleClick = (el: HTMLDivElement, e: MouseEvent) = ...

Django Angular 403 Error: CSRF-cookie not accepted. Reason: CSRF token is missing or incorrect

Currently, I am working on developing a Single Page Application (SPA) with Angular6 integrated with Django. However, I am facing an issue where Django is not accepting the csrftoken cookie that I am sending along with my requests. In my settings.py file, I ...

Error: Attempting to access the 'presence' property of an undefined value

Having trouble with calling loading/Toast/Alert in Ionic2 under the current scenario. Being a newcomer to Ionic development, I'm struggling to understand it. I realize it's a trivial mistake. var dg = document.getElementById('btnregis&apos ...

The name 'Landbot' cannot be located. Have you meant to type '_landbot' instead?

I'm currently in the process of integrating Landbot into my React.js application with TypeScript. I'm following this [doc] 1. However, I'm facing an issue where the code inside useEffect (new Landbot.Container) is causing an error. 'C ...

The vertical bar chart from amcharts is lacking labels

The graph attached displays labels alternatively, which appears to be a default setting of the amcharts. Is there a way we can modify it to show all the labels? Refer to the screenshot provided below. The implementation is done using amcharts in angular c ...

How does Angular2 indicate the modification in a segment of Component?

ReactJs utilizes virtual DOM for rendering changes, whereas Angular2 does not have a virtual DOM. However, Angular2 is reactive similar to ReactJS. In Angular2, with any change, the whole component does not need to be modified, only the portion of the co ...

I encounter an issue when trying to declare an enum in TypeScript

At line 26 in my typescript file, the code snippet below shows an enum definition: export enum ItemType { Case = 'Case', Study = 'Study', Project = 'Project', Item = 'Item', } I am currently using Visual Stu ...

Typescript often fails to recognize that every code path within a function should return a value

Is it possible to inform TypeScript that all potential code paths in a function will return a value? In my scenario, I provide two numeric arrays as input, verify their monotonically increasing nature, and then retrieve a value based on specific condition ...

The challenge with the Optional Chaining operator in Typescript 3.7@beta

When attempting to utilize the Typescript optional chaining operator, I encountered the following exception: index.ts:6:1 - error TS2779: The left-hand side of an assignment expression may not be an optional property access. Here is my sample code: const ...

Guide on incorporating text input areas into specific positions within a string

Looking for a way to replace specific words in a string with input fields to enter actual values? For example... Dear Mr. [Father_name], your son/daughter [name] did not attend class today. This is what I want it to look like... Dear Mr. Shankar, your ...

Relentless Recursion in Angular's Parent Component

Take a look at the Stackblitz to replicate the issue Hey there! I have an Angular7 application with a parent component named timesheet, and a child component called row. What I'm trying to achieve is having the parent component, timesheet, dynamicall ...