The issue of linking .then() functions

I've been struggling to grasp the concept of Promises/then-ables for a while now. Currently, I am working with NextJS.

My goal is to chain together the following steps:

  1. Retrieve data from an API
  2. Save the data
  3. Modify the data to create a component (without causing an infinite loop)

I'm facing difficulty in obtaining the correct data for step #3. Despite trying different approaches, I seem to be stuck at this stage.

For this purpose, I am utilizing the useEffect hook, although I acknowledge there might be alternative methods available as well: https://nextjs.org/docs/basic-features/data-fetching/client-side

export default function Survey() {
  const [dataDB, setDataDB] = useState('');
  let roles;

  function createCards(rolesArr) {

    let role1 = tabs.find(x => x.id == rolesArr[0])
    let role2 = tabs.find(x => x.id == rolesArr[1])
    let role3 = tabs.find(x => x.id == rolesArr[2])

    // the above is null
    // the below is also null:
    //     let role1 = tabs.find(x => x.id == dataDB[0])

    roles.push(role1)
    roles.push(role2); 
    roles.push(role3); // component will map over these 3
  }

  useEffect(() => {
    fetch('example.com/api')
      .then((response) => response.json()) // 1. Retrieves an array like [0, 3, 5]
      .then((data) => {
        setData(dataDB) // 2. Utilizing hook to setData, data will be stored in the database later
      }
     .then((rolesArr) => createCards(rolesArr)) // 3. Modifying data for the component
    })
  )  

  return ( 
    { 
      roles.map((path) => (
        <Card key={path.id}>
          <Text>{path.title}</Text>
        </Card>
      ))
    } 
  )
}

Answer №1

You seem to be facing quite a few issues.

Undefined Roles

let roles; initializes a variable with the value of undefined.

When you try to use it as an array later on, such as in roles.map((path) => ( you will encounter an error.

To resolve this, ensure you define it as an array from the start.

A Tiny Typo

.then((data) => {
        setData(dataDB) // 2. Using hook to setData, will store in database later
      }

You are missing a closing parenthesis at the end there.

Undefined rolesArr

The value returned by:

.then((data) => {
        setData(dataDB) // 2. Using hook to setData, will store in database later
      }

… is undefined because there is no explicit return statement. Therefore, subsequent then() callbacks will receive undefined.

There's no need for an additional promise creation here since what you want can be done within the existing function.

  .then((data) => {
    setData(dataDB);
    createCards(dataDB);
  });

Creating Cards Issue

 roles.push(role1)
 roles.push(role2); 
 roles.push(role3); // component will map over these 3

You face a similar problem here with roles being undefined and not an array.

Moreover, because createCards is executed asynchronously, this code runs after roles.map((path) => (, rendering the changes ineffective.

Instead of mutating a non-existent array, create a new one and store it in state. State updates trigger re-renders, enabling the component to access and iterate over the array.

A typical solution involves:

const [roles, setRoles] = useState(null);

function createCards(rolesArr) {
    // etc
    setRoles([role1, role2, role3]);
}

// etc

if (roles === null) {
    return <p>Loading</p>;
}

return roles.map(etc etc);

Answer №2

When working with the .then() method, it is important to ensure that you return the output from the previous callback function in order to chain multiple .then() calls together. Here's a quick example:

fetchData()
  .then((response) => {
    console.log(response.json())
    return response.json()
  }).then((values) => {
    console.log(values)
    return values.filter((value) => value > 0)
  }).then((positiveValues) => {
    console.log(positiveValues)
    return positiveValues;
  })

In this scenario, the response.json() is printed and then passed on as a value for the subsequent .then() callback to utilize.

To adapt this for your situation, make sure to return the desired value within the second callback like so:

fetch('example.com/api')
      .then((response) => response.json()) // 1. Retrieves an array such as [0, 3, 5]
      .then((data) => {
        setData(dataDB) // 2. Utilizing hook to store data in database at a later point
        return dataDB;
      }).then((rolesArr) => createCards(rolesArr)) // 3. Adjusting data for component usage
    })

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

Passing data from a parent component to a child component in Next.JS 13

Struggling to make NextJS work seamlessly with props and passing them between components? It feels like a React-specific challenge, but after scouring Google for answers, the results are scarce. My goal is simple: send a useState value along with its sette ...

What is the best way to attach a CSS class using an onclick function?

I need to dynamically apply a CSS class to a specific div when clicked using JavaScript. Here is the HTML structure: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv=&qu ...

What is the best way to utilize JSON data stored in a Jekyll _data folder?

As per the documentation on Jekyll, it is mentioned that you can access YAML, JSON, and CSV files located in the `_data` directory using `{{ site.data.filename }}`. I have a geoJson file named `chapters.json` which consists of point features. While I am a ...

What are the steps to reset the Firebase server in order to allow the deployment of functions

After using firebase deploy --only functions, an error appeared in my React code and I had to use control-C to stop the deployment on my Mac. Now, when attempting to redeploy to Google servers, the following error is encountered: firebase.js -> build/f ...

The 'xxx' type does not have an index signature, so the element is implicitly assigned an 'any' type

I'm currently facing an issue with TypeScript. The error message I'm encountering is related to the following section of code: The Interface: export default interface IUser { username: string; email?: string; isActive: boolean; group: s ...

A guide on applying bold formatting to a specific section of text in React

I have a collection of phrases structured like so: [ { text: "This is a sentence." boldSubstrings: [ { offset: 5, length: 2 } ] } ] My goal is to display each phrase as a line using the following format: ...

The code is running just fine when tested locally, but it seems to encounter an issue when accessed remotely, yielding

Currently, I am in the process of developing a dual twin setup using a Raspberry Pi. The goal is to simulate a continuous transmission of body temperature data, which is then sent to a server that stores the information in a MongoDB database. Everything fu ...

Is it possible to include a base url for imports in React JS?

Conventional method for adding imports: import Sample from ‘../../../components/signup’ I want to simplify imports by removing the front dots and slashes: import Component from ‘components/signup’ Is there a way to set a base URL for imports to ...

Instruction failed to produce HTML output

Currently facing a challenge with my code - I have a dynamically created span (via ng-repeat). <span my-size id="abc"></span> <span my-size id="def"></span> <span my-size id="ghi"></span> The goal is to extract the id ...

End the streaming process in React Native using React Navigation

Currently, I am developing an application with two distinct streams (A and B) that can both be accessed from the home screen. However, I have encountered a persistent issue. Whenever I enter stream A, everything functions as expected. But when I try to ac ...

Resizing popups upon button activation

Hey there! I have a popup with a button that reveals random text containing between 0 to 32 words when clicked. The issue is, the popup keeps resizing based on the length of the text, causing the button to move around. Is there a way I can keep the button ...

What is the best way to send a file to a JavaScript function within Django?

I am in the process of integrating the PhylD3 library into a Django Template. The CSS and JS files have been integrated into the Django static directory. However, I am unsure about the most efficient way to load the XML file in the template. Template - ...

Despite successfully passing props into V-for, the output does not display the props as expected

I've been attempting to accomplish a straightforward task, but for some reason, it's not working and I can't figure out why. Within the parent component, App.vue, I have the following: data() { return { servers: [ { ...

Transforming the appearance of the menu element in Vue using transitions

In my Vue app, I have this SCSS code that I'm using to create a smooth transition effect from the left for a menu when the isVisible property is set to true. However, I am encountering an issue where the transition defined does not apply and the menu ...

Iframe form submissions

I am interested in accomplishing the following task. My objective is to submit a form to my booking engine and show the results on either a new page or within a Div element. Ideally, when the user clicks the submit button, it would display an Iframe or re ...

The JSON reviver function is still not returning anything even when explicitly using the return

function _quotedText(data, config) { var pathKeys=config.customKey; console.log(pathKeys); //prints os_platform var inAuth_data=(JSON.parse(JSON.parse(JSON.parse(data["event.fields.custom_fields.inauth_device_data"])), (key, value) =& ...

Using NextJS with Storybook: The Issue with Optional Chaining

https://i.stack.imgur.com/lY2F1.png rehype-ignore - index.js contains the following code snippet: import { visit } from 'unist-util-visit'; const rehypeIgnore = (options = {}) => { const { openDelimiter = 'rehype:ignore:start', ...

Transitioning from using a jQuery get request to utilizing Vue.js

Looking to transition from JQuery-based js to Vue as a newcomer to JavaScript. Seeking guidance on making a get request and displaying the retrieved data. What approach would you recommend for this task? Here's the HTML snippet: <div> <di ...

The CSS styling for a pie chart does not seem to be functioning properly when using jQuery's

https://i.stack.imgur.com/kEAKC.png https://i.stack.imgur.com/03tHg.png After examining the two images above, it appears that the CSS is not functioning properly when I try to append the same HTML code using JavaScript. Below is the snippet of my HTML co ...

A guide on utilizing webpack devServer proxy within a create react app

Currently, I am in the process of developing a new application with create-react-app and I am looking to incorporate some proxies into my code. In the past, I utilized webpack's devServer for this purpose. module.exports = { ... devServer: { ...