0

I am new to Node and react, please bear with me if there are numpty mistakes.

I want to make a POST request to backend , and get back a response. The response is an array with objects inside. Then, I would like to map the array and render it in a component.

I can get the response in frontend and log in console as following:

reading react-dev-tools and the component of VideoConferenceRoom shows:

[
  {
    "name": "State",
    "value": [
      {
        "id": 1,
        "video_room_pw": "57e2c460-3e7f-11eb-9c9c-a329bc0bc2e2",
        "video_room_name": "57e2eb70-3e7f-11eb-9c9c-a329bc0bc2e2",
        "video_hashed_room_name": null,
        "video_room_url": "meet.jit.si/57e2eb70-3e7f-11eb-9c9c-a329bc0bc2e2"
      },
      {
        "id": 2,
        "video_room_pw": "13e074c0-3e8d-11eb-8192-4bf84e5d2275",
        "video_room_name": "13e074c1-3e8d-11eb-8192-4bf84e5d2275",
        "video_hashed_room_name": null,
        "video_room_url": "meet.jit.si/13e074c1-3e8d-11eb-8192-4bf84e5d2275"
      }
    ],
    "subHooks": []
  },
  {
    "name": "Effect",
    "value": "ƒ () {}",
    "subHooks": []
  }
]

console logging response.videoRooms:

image

But when I update the response array in useState hook, nothing is being mapped onto the page. The problem seems to be not able to set the current state in useState hook currentVideoRoom, because it logged something empty in console. Can anyone help? Thank you in advance.

My react code:

import React, { useEffect, useState } from "react";
import { Paper } from '@material-ui/core';

const VideoConferenceRoom = ({currentWorkspace}) => {
    const [currentVideoRoom, setCurrentVideoRoom] = useState([]);
    let listItems; 
    useEffect(()=>{
        const getVideo = async()=>{
            const body = {currentWorkspace};
                try{
                    const getVideoInfo = await fetch(`http://localhost:4000/workspace/${currentWorkspace}/video/rooms`,{
                        method:"POST",
                        headers: {
                            "Content-Type":"application/json",
                            "x-access-token": localStorage.getItem("token")
                        },
                        body: JSON.stringify(body)
                    })
                    const response = await getVideoInfo.json();             
              
                    setCurrentVideoRoom(prevItems => [...prevItems, response.videoRooms])
                  
                    console.log(currentVideoRoom);
                    listItems = response.videoRooms;
                }catch(e){
                    console.error(e.message);
                }
            }
        getVideo();
    },[]);

   
return(
    <>
            <h1>Join the video meetings!</h1>
            {currentVideoRoom.map((item)=>{
                    <Paper elevation={3}>
                        {item}
                    </Paper>
            })}   
                    </>
    )
};

export default VideoConferenceRoom;

console logging getVideoInfoFromSameWorkspaceArr in backend :

[ { id: 1,
    video_room_pw: '57e2c460-3e7f-11eb-9c9c-a329bc0bc2e2',
    video_room_name: '57e2eb70-3e7f-11eb-9c9c-a329bc0bc2e2',
    video_hashed_room_name: null,
    video_room_url: 'meet.jit.si/57e2eb70-3e7f-11eb-9c9c-a329bc0bc2e2' },
  { id: 2,
    video_room_pw: '13e074c0-3e8d-11eb-8192-4bf84e5d2275',
    video_room_name: '13e074c1-3e8d-11eb-8192-4bf84e5d2275',
    video_hashed_room_name: null,
    video_room_url: 'meet.jit.si/13e074c1-3e8d-11eb-8192-4bf84e5d2275' } ]

my code in backend :

const knex = require("../models/knex");

exports.postVideoShowRoom = async(req,res)=>{
  const {currentWorkspace} = req.body;
  try{
    //get users from same workspace , more than 1 user in ws?
    let getCurrentWorkspace = await knex('workspace').select().where('workspace_name', currentWorkspace);
    console.log(getCurrentWorkspace,'this is getCurrentWorkspace')
    let getVideoIdFromSameWorkspace ;
    let getVideoInfoFromSameWorkspace ;
    let getVideoInfoFromSameWorkspaceArr = [];

    for (let item of getCurrentWorkspace){
      getVideoIdFromSameWorkspace = await knex('video_workspace').select().where('workspace_id', item.id);
      console.log(getVideoIdFromSameWorkspace, 'this is getVideoIdFromSameWorkspace')
    }
    for (let item of getVideoIdFromSameWorkspace){
      getVideoInfoFromSameWorkspace = await knex('video').select().where('id', item.video_id);
      getVideoInfoFromSameWorkspaceArr.push(getVideoInfoFromSameWorkspace[0]);
    }
    console.log(getVideoInfoFromSameWorkspaceArr, 'this is getVideoInfoFromSameWorkspaceArr')

    
  res.json({
    videoRooms: getVideoInfoFromSameWorkspaceArr,
  })
}catch(e){
    console.error(e.message);
}
}
8
  • 2
    Ignoring the console log (because react state updates are asynchronous) does your render actually work? videoRooms also appears to be an array, so unless you meant to nest the array I think you should also spread it, setCurrentVideoRoom(prevItems => [...prevItems, ...response.videoRooms]). After this you'll likely see an error that react can't render objects, as item will be one of those room objects. Commented Dec 15, 2020 at 8:45
  • It's just the logging that wont work. The update is asynchronous. console.log(currentVideoRoom) will display the value of currentVideoRoom from the closure. I.e. this value will never change until the next render. Is it not working other than that? Commented Dec 15, 2020 at 8:48
  • console.log(currentVideoRoom); will show the old value due to asynchronous nature of state, but rendering should work. Try updating your code setCurrentVideoRoom(prevItems => [...prevItems, ...response.videoRooms]) Commented Dec 15, 2020 at 8:52
  • The rendering does not work, empty page besides <h1> heading @DrewReese Commented Dec 15, 2020 at 8:57
  • Any errors then? Check the network tab to ensure the POST request is successful. Check the react-dev-tools to see what values of state are. Commented Dec 15, 2020 at 8:59

1 Answer 1

1

if response like this:

  const response = { videoRooms: [ { id: 1,
    video_room_pw: '57e2c460-3e7f-11eb-9c9c-a329bc0bc2e2',
    video_room_name: '57e2eb70-3e7f-11eb-9c9c-a329bc0bc2e2',
    video_hashed_room_name: null,
    video_room_url: 'meet.jit.si/57e2eb70-3e7f-11eb-9c9c-a329bc0bc2e2' },
  { id: 2,
    video_room_pw: '13e074c0-3e8d-11eb-8192-4bf84e5d2275',
    video_room_name: '13e074c1-3e8d-11eb-8192-4bf84e5d2275',
    video_hashed_room_name: null,
    video_room_url: 'meet.jit.si/13e074c1-3e8d-11eb-8192-4bf84e5d2275' } ]
  };

use:

setCurrentVideoRoom((prevItems) => [...prevItems, ...response.videoRooms]);

and change render to something like:

  return (
    <>
      <h1>Join the video meetings!</h1>
      {currentVideoRoom.map((item) => (
        <Paper elevation={3}>
          <p>{item.id}</p>
          <p>{item.video_room_name}</p>
          <p>{item.video_room_url}</p>
        </Paper>
      ))}
    </>
  );
Sign up to request clarification or add additional context in comments.

2 Comments

you can't render Object in JSX, only plain properties
Thank you! it solves it. And thank you to others who have helped to clear my concepts out!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.