Proper Techniques for Parsing JSON Data

Currently, I am utilizing the PokeAPI. My approach involves making fetch requests to obtain JSON data from a specific endpoint, and then attempting to parse and return it. The function responsible for this task can be located below:

function getPokemon(id){

    pokemonData = {
        name:"",
        image:"",
        id:id,
        description:""
    }
    
    // Documentation: https://pokeapi.co/docs/v2#pokemon-species
    fetch(`https://pokeapi.co/api/v2/pokemon-species/${id}/`)
      .then((response) => response.json())
          .then((data) => {
        
            pokemonData.description = data.flavor_text_entries[0].flavor_text.toString()
            
          }
        )
    
    // Documentation: https://pokeapi.co/docs/v2#pokemon
    fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`)
      .then((response) => response.json())
          .then((data) => {
        
            pokemonData["image"] = data.sprites.other["official-artwork"].front_default.toString()
            pokemonData["name"] = data.name.toString()
            
          }
        )

    return pokemonData
}

After receiving the data, my attempts to access attributes show blank values, despite the object displaying the correct information:

https://i.sstatic.net/a15KY.png

I am uncertain about what is going wrong in this scenario. I have experimented with various attribute access formats such as data.name versus data["name"], but none seem to have an impact. Any assistance on this matter would be greatly appreciated.

Answer №1

Your solution is accurate for solving the problem at hand, although it could benefit from a more efficient use of `async / await` and promises.

To optimize the code, consider using `await` on both `fetch` calls to run the requests simultaneously instead of sequentially. This can be achieved by allowing both `fetch` calls to execute in parallel and waiting for both to complete using `Promise.all()`.

Once both requests have been fulfilled, you can construct your `pokemonData` object based on the data retrieved from each source.

async function getPokemon(id) {
  const speciesRequest = fetch(`https://pokeapi.co/api/v2/pokemon-species/${id}/`)
    .then((response) => response.json())
    
  const pokemonRequest fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`)
    .then((response) => response.json())
  
  try {
    const [speciesData, pokemonData] = await Promise.all([speciesRequest, pokemonRequest]);

    return ({
      id,
      image: pokemonData.sprites.other["official-artwork"].front_default,
      name: pokemonData.name,
      description: speciesData.flavor_text_entries[0].flavor_text.toString()
    });
  catch (error) {
    return Promise.reject(error);
  }
}

Answer №2

While in the process of writing this, I had a breakthrough moment where everything suddenly made sense. Previously, I mistakenly believed that using .then() would automatically make the response synchronous as indicated by various online sources.

However, this assumption turned out to be incorrect.

To resolve the issue of my function running ahead of the fetch operation, I needed to convert my function into an async function to properly await the fetch call. The corrected code looks like this:

async function getPokemon(id){
    
    pokemonData = {
        name:"",
        image:"",
        id:id,
        description:""
    }
    
    // Documentation https://pokeapi.co/docs/v2#pokemon-species
    await fetch(`https://pokeapi.co/api/v2/pokemon-species/${id}/`)
      .then((response) => response.json())
          .then((data) => {
        
            pokemonData.description = data.flavor_text_entries[0].flavor_text.toString()
            
          }
        )
    
    // Documentation: https://pokeapi.co/docs/v2#pokemon
    await fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`)
      .then((response) => response.json())
          .then((data) => {
        
            pokemonData.image = data.sprites.other["official-artwork"].front_default
            pokemonData.name = data.name
            console.log(data.name)
            
          }
        )
    return pokemonData
}

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

unable to update database using jquery ajax

Hello everyone, this is my first time posting on Stackoverflow! I am facing an issue while trying to run an "Insert" query using Jquery's $.ajax function. Upon checking the network tab on Chrome Dev Tools, it seems like my file is being loaded but th ...

Error: Property "rotation" cannot be redefined

After setting up all the necessary dependencies using npm and bower for a project on a different laptop, I encountered an error when trying to run it locally. The error message reads: Uncaught TypeError: Cannot redefine property: rotation at (line 7542 i ...

Tracking the number of images and adjusting the counter as the user scrolls

I am working on a project where I have a series of images displayed in a column. I would like to add a dynamic counter to indicate which image is currently in focus based on the scroll position. Feel free to check out the demo <div class="counter"> ...

Is there a way to export a specific portion of a destructuring assignment?

const { a, ...rest } = { a: 1, b: 2, c: 3 }; If I want to export only the rest object in TypeScript, how can I achieve that? ...

Utilizing Angularfire OAuth for Facebook authentication in login strategy

After successfully implementing the code below in the loginCtrl controller and login.html, I encountered some issues with setting up the workflow correctly. My goal is to achieve something like this: //check if the current $scope has authData //if so red ...

Discover information based on attribute value with MarkLogic

I am working on a MarkLogic 8 database and I have the following code snippet: declareUpdate(); var book0 = { id: fn.generateId({qwe: 'book'}), username: 'book', password: 'pass' }; var book1 = { id: fn.generateId({asd ...

How can I resolve the error message "Uncaught TypeError: Cannot use 'in' operator to search for 'length' in" to successfully display my data?

When I send an ajax request to iterate over multiple arrays, I encounter the following error: Uncaught TypeError: Cannot use 'in' operator to search for 'length' in $.get(url).done(function(data){ var data = JSON.stringify(data); v ...

Ways to activate a different jQuery event by utilizing the output from a previously run jQuery event

I have a button on my website that looks like this: <a id="btn" class="button">Click Me!</a> When this button is clicked, it triggers a jQuery function as shown below: $("#btn").on("click", function() { $.ajax({ url: 'index.php&ap ...

What is the best method to incorporate a Node.js package into a Java program?

In the process of enhancing a server built in Java, I stumbled upon an excellent Node.js package on npm that offers an API I wish to utilize from the Java server. What is the best approach for establishing a connection or bridge between these two technolo ...

Unleashing the power of conditional exports in package.json

Within my package.json, I define an exports section: "exports": { "import": "./dist/a.es.js", "require": "./dist/b.umd.js" }, However, during development, I wish to use different pa ...

Azure-Graph is reporting an error: 'Invalid or missing Access Token.'

In my Node.js project, I effortlessly integrate azure APIs. Logging in: const MsRest = require('ms-rest-azure'); MsRest.loginWithServicePrincipalSecret(keys.appId, keys.pass, keys.tenantId); Creating a resource group: const { ResourceManageme ...

What is preventing me from using jQuery to dynamically insert HTML onto the page?

Below is the HTML code for a Bootstrap Modal dialog box: <div class="modal fade" id="rebateModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> ...

What is the best way to organize JavaScript code for handling multiple variables from multiple form elements while also preserving the selected choices?

For instance, suppose I have an HTML form like this: <form role="search" method="get" id="searchform" action="" > <!-- DIRECT SEARCH INPUT TO SEARCH STRING --> <input type="text" value="" name="s" id="s" /> <input type=" ...

Uploading information to a server using Angular.js

I am currently working on developing an application with the following code snippet: function attendeeCtrl($scope, $http) { $scope.submit = function () { console.log($scope.noattendees); $http({ method: 'POST', ...

What is the significance of incorporating vinyl-source-stream into gulp in my workflow?

Recently, I've been experimenting with gulp and browserify to convert my .jsx files into .js files. var gulp = require('gulp'); var browserify = require('browserify'); var reactify = require('reactify'); gulp.task(&apos ...

The MUI Autocomplete filterOptions is not effectively filtering out all options as expected

Hey there! I'm facing an unusual situation with my Autocomplete feature, which has been heavily customized to meet certain restrictions and requirements. The issue I am encountering is related to filtering. Despite successfully filtering the results ...

Issues may arise when attempting to parse AJAX responses using Javascript/JQuery AJAX

There are many posts on this topic, but I am having trouble finding the specific information I need. Here is where I am struggling: I have an AJAX request for an ID and an integer (which will be used as a margin to apply on the DOM later). This is the re ...

Information derived from a provided URL

I am currently developing a Spotify stats app, and I am facing an issue with creating a context to store the token provided by the app in the URL when a user logs in. TokenContext.js: import React, { useEffect, useState } from "react"; // token ...

Web-based client services

Context: An HTML file I'm working with takes in multiple parameters and utilizes JavaScript to dynamically render the content. The page pulls data from various local XML files for processing. For instance, accessing service.html?ID=123 displays info ...

What is the best way to automatically adjust a panel's width and height based on the user's screen resolution?

My page is connected to a masterpage. Within this page, I have an update panel that contains an ASP.NET panel. The panel includes a gridview displaying data from the database. Currently, I have set a fixed width and height for the panel. However, if the u ...