ERROR Error: Uncaught (in promise): ContradictionError: The variable this.products is being incorrectly identified as non-iterable, although it

Seeking a way to extract unique values from a JSON array.

The data is fetched through the fetch API, which can be iterated through easily.

[please note that the product variable contains sample JSON data, I actually populate it by calling GetAllProducts()]

products = 
[
  {
    "name": "APPLE 27 inch THUNDERBOLT DISPLAY",
    "show_room": "A iCenter",
    "stock": "1",
    "type": "DISPLAYS",
    "category": "APPLE",
    "id": "101"
  },
  {
    "name": "APPLE WIRELESS KEYBOARD",
    "show_room": "B iCenter",
    "stock": "2",
    "type": "MOUSE",
    "category": "MAC ACCESSORIES",
    "id": "107"
  }
]

An error occurs when attempting to execute the function: getDistinctCategoryValues()

This snippet is from my .ts file

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-product-list',
  templateUrl: './product-list.page.html',
  styleUrls: ['./product-list.page.scss'],
})
export class ProductListPage implements OnInit {

  constructor(private dataService: DataService,
              private router: Router) {
    this.GetAllProducts();
    this.getDistinctCategoryValues();
  }

  products: any;


  ngOnInit() {
  }

  async GetAllProducts() {
    const response = await this.dataService.GetProducts();
    const dataService = await response.json();
    this.products = dataService;
    console.log(this.products);
  }

  getDistinctCategoryValues() {

    const lookup = {};
    const result = [];

    console.log(this.products);
    for (const item of this.products) {
      const currentVar = item.category;

      if (!(currentVar in lookup)) {
        lookup[currentVar] = 1;
        result.push(currentVar);
      }
    }

    console.log(result);
    return result;

  }

}

When running getDistinctCategoryValues(), an error is thrown:

ERROR Error: Uncaught (in promise): TypeError: this.products is not iterable.

A peculiar issue arises where,

  1. While console.log() within GetAllProducts() shows all data correctly stored in the products variable
  2. Subsequent console.log() within getDistinctCategoryValues() displays the product variable as undefined

Perplexed on what went wrong. Why does the data disappear just one line later? [refer to the constructor]. The API runs smoothly without any errors.

[By the way, utilizing https://www.npmjs.com/package/json-server for handling JSON]

Answer №1

The reason for this issue is that your GetAllProducts function is asynchronous and it waits for a response from the server using

const response = await this.dataService.GetProducts()
. This means that any code inside the GetAllProducts function will not run immediately. As a result, anything after the async function will execute normally, causing `this.product` to always be undefined. To fix this problem, you can either move the getDistinctCategoryValues() function inside the await block, modify GetAllProducts so it returns products which can then be used in getDistinctCategoryValues(), or consider using generator functions.

Answer №2

To make the necessary adjustment, simply switch from using 'any;' to declaring an empty array with 'products = [];'. Everything else should function properly without any alterations.

Additionally,

The initialization process won't function as intended. It's essential to relocate 'this.getDistinctCategoryValues();' to the ngOnInit method or explicitly call 'this.GetAllProducts()' to ensure proper execution.

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

Nest JS is currently experiencing difficulties with extending multiple classes to include columns from other entities

Currently, I am immersed in a new project that requires me to enhance my entity class by integrating common columns from another class called BASEMODEL. import { Index, PrimaryGeneratedColumn } from "typeorm"; export class BaseModel { @Prima ...

React HTML ignore line break variable is a feature that allows developers to

Can you help me with adding a line break between two variables that will be displayed properly in my HTML output? I'm trying to create an object with a single description attribute using two text variables, and I need them to be separated by a line b ...

The latest URL is not launching in a separate tab

Looking for some assistance with this code snippet: <b-btn variant="primary" class="btn-sm" :disabled="updatePending || !row.enabled" @click="changeState(row, row.dt ? 'activate' : 'start&apo ...

Guide on creating a custom type for an object utilizing an enum framework

Enumerating my shortcuts: export enum Hotkey { MARK_IN = 'markIn', MARK_OUT = 'markOut', GO_TO_MARK_IN = 'goToMarkIn', GO_TO_MARK_OUT = 'goToMarkOut' } I am now looking to define a type for a JSON ob ...

Why is the axios.get promise not getting resolved?

I am currently working on fetching data from MongoDB atlas within a React app. However, despite using .then and .catch with axios.get(), I am encountering an unresolved promise. Here is the code snippet: const entry = axios.get('http://localhost:3001 ...

Is there a way to divide or segment excessive JSON Files using AWS glueContext prior to their conversion to JSON format?

I am currently working on converting a large 20GB JSON gzip file to parquet format using AWS Glue. I have set up a job using Pyspark and included the code below. During this process, I encountered the following WARN message: LOG.WARN: Loading one large ...

Seeking a more deliberate option instead of using $(window).load, one that is not as quick as $(document)

Currently, my goal is to utilize JavaScript to conceal my preloader once the DOM and key elements have been loaded. The issue lies in the fact that various iframes on my page can significantly slow down this process. It seems that using jQuery's $(do ...

Several onclick events on a single webpage

Despite numerous attempts and hours of reading, I am still unable to figure this out. There are two different types of card elements, each with a selection of 15 different color choices. Aside from using "a", is there anything else I can try to solve this? ...

Implementing fetch within a custom hook to display a loader within a return function

customFetch hook: import React, { useState, useEffect } from 'react'; const customFetch = (url, options) => { const [response, setResponse] = useState(null); const [error, setError] = useState(null); useEffect(() => { (async () ...

NodeJS domain error handling failing to catch ReferenceError exceptions

I'm currently facing some challenges with domains in NodeJS. I've set up middleware functions to wrap every call in my web application within a domain in order to capture errors, process them, and return informative error messages. While this se ...

Creating HTML elements using JavaScript compared to importing an HTML fileIn JavaScript,

I am currently in the process of building a website that is entirely driven by JavaScript. Aside from the index page, I do not use any HTML pages at all. Instead, I fetch JSON data for every query and then dynamically generate HTML within the JavaScript to ...

The error encountered is: `Exception: startDate.getTime is not a valid function

const [currentDate, setCurrentDate] = useState(new Date()); const fetchDataFromAPI = () => { let timeStamp = Number(currentDate.getTime()); axios.get( `https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=BTC,USD,EUR& ...

How can I assign a true or false value to an input variable in HTML using AngularTS?

I copied the following HTML code: <tag-input fullWidth id="inputDir" formControlName="inputDir" [modelAsStrings]="true" [placeholder]="'choice feature'" ...

Once the Ionic platform is prepared, retrieve from the Angular factory

I have created a firebase Auth factory that looks like this: app.factory("Auth", ["$firebaseAuth", "FIREBASE_URL","$ionicPlatform", function($firebaseAuth, FIREBASE_URL, $ionicPlatform) { var auth = {}; $ionicPlatform.ready(function(){ ...

Leveraging the power of ES6 syntax in Node scripts with Babel

My npm CLI tool utilizes ES6 syntax from BabelJS, specifically arrow functions. Within the entry point of my tool, I'm using the following require: require('babel-core/register'); var program = require('./modules/program.js'); I ...

NextJs does not allow external synchronous scripts

I am currently working with Next.js version 11.x Whenever I attempt to add an external script like the example below, I encounter an error when executing the yarn build. <Head> <link rel="stylesheet" type=" ...

What is the best way to change an existing boolean value in Prisma using MongoDB?

Exploring prisma with mongoDb for the first time and faced a challenge. I need to update a boolean value in a collection but struggling to find the right query to switch it between true and false... :( const updateUser = await prisma.user.update({ where: ...

What could be causing my tab code to not function flawlessly?

I am attempting to implement a tab concept on my website. For example, the tab names are Monday...Tue.. up to Sunday. Each tab contains an image file based on the days (size 460*620). When I run my page, it shows all images, but what I need is for the imag ...

Creating a custom design for ng-bootstrap accordion using CSS styling

I've encountered an issue with my Angular 2 component that utilizes an accordion from ng-bootstrap. While the functionality works perfectly, I'm facing a problem with applying custom styles using the .card, .card-header, and .card-block classes o ...

Locate items that possess identical property values and append them to a new array as a property

I am dealing with an array containing objects that have a specific property called "operationGroup" with the sub-property "groupId". Here is an example of the array structure: [{ operation: 11111, operationGroup: null }, { operation: 22222, ...