Home > Software engineering >  Await result of API call and update list component
Await result of API call and update list component

Time:11-03

I am calling a REST API and return chat rooms. Those get returned fine, as I can see in the payload of the object via the console.

Now I want to display this in a list.

I was able to display a list and download the chat rooms, but not combine both. This is what I did:

import * as React from 'react';

export default function ChatRoomList({param1}) {
  var x = getChatRoom(param1)
  console.log(x)

    return  (
        <div>
             <li>{param1}</li>
             <li> asd  </li>
             <li> asd  </li>
        </div>
    );
  }


async function getChatRoom(status) {

    // status could be either 'open' or 'room'
    var dict = { 
        chatType: status,
        };

    var adminChats = await callKumulosAPIFunction(dict, 'getAdminChat')
    return adminChats
}

Now I did try to simply await the first getChatRoom(param1) call. But I can only await inside an async function. I then tried to add the async keyword to the export function, but this would crash the whole app.

How would the workflow be here? And how would I map the result from getChatRoom onto a listview?

The result of the adminChats (console.log(adminChats)):

enter image description here

CodePudding user response:

You need to use useEffect hook to get remote data:

export default function ChatRoomList({param1}) {

  React.useEffect(()=>{
    (async () => {
        var x = await getChatRoom(param1)
        console.log(x)
    })()
  },[])  

    return  (
        <div>
             <li>{param1}</li>
             <li> asd  </li>
             <li> asd  </li>
        </div>
    );
  }

If the data returned from getChatRoom is an array and you want to show it, you need to save the response in a state, or the component will not re-render:

export default function ChatRoomList({param1}) {
  const [chatRooms, setChatRooms] = React.useState([]);
  React.useEffect(()=>{
    (async () => {
        var x = await getChatRoom(param1)
        setChatRooms(x)
    })()
  },[])  

    return  (
        <div>
             <li>{param1}</li>
             {chatRooms.map((chatRoom , index) => {
                return <li key={index}>{JSON.stringify(chatRoom)}</li>
             })}
        </div>
    );
  }

async function getChatRoom(status) {

    // status could be either 'open' or 'room'
    var dict = { 
        chatType: status,
        };

    var adminChats = await callKumulosAPIFunction(dict, 'getAdminChat')
    return adminChats.payload
}

I suggest you to read the documentation about React hooks and lifecycle management:

  1. https://reactjs.org/docs/hooks-intro.html

  2. https://reactjs.org/docs/state-and-lifecycle.html

CodePudding user response:

You need to use useEffect hook to call the API. Read more about hooks

import * as React from 'react';

     function getChatRoom(status) {
        const [chats, setChats] = React.useState([]);
    
        const getChart = async (status) => {
            // status could be either 'open' or 'room'
            const  dict = { 
            chatType: status,
            };
    
            const adminChats = await callKumulosAPIFunction(dict, 'getAdminChat');
            setChats(adminChats);
        };
    
        React.useEffect(() => {
            getChart(status)
        }, [status])
    
    
        return { chats };
    };
    
    export default function ChatRoomList({param1}) {
      const { chats } = getChatRoom(param1)
      console.log(chats)
    
        return  (
            <div>
                 <li>{param1}</li>
                 {chats?.map((chatRoom , index) => {
                   return <li key={index}>{JSON.stringify(chatRoom)}</li>
                 })}
            </div>
        );
      }

Dependencies argument of useEffect is useEffect(callback, dependencies)

Let's explore side effects and runs:

Not provided: the side-effect runs after every rendering.

import { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    // Runs after EVERY rendering
  });  
}

An empty array []: the side-effect runs once after the initial rendering.

import { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    // Runs ONCE after initial rendering
  }, []);
}

Has props or state values [prop1, prop2, ..., state1, state2]: the side-effect runs only when any dependency value changes.

import { useEffect, useState } from 'react';

function MyComponent({ prop }) {
  const [state, setState] = useState('');
  useEffect(() => {
    // Runs ONCE after initial rendering
    // and after every rendering ONLY IF `prop` or `state` changes
  }, [prop, state]);
}
  • Related