0

Context

At the moment I am working on a project where I want to get data, more specifically a list/Array of Strings, from my Python API and display that list with React. I am getting the list and it looks completely fine. No undefined values, everything is a String and it really is an Array. So the retrieved data appears to be valid. After retrieving the data I want to set it as a state variable in React so that I can pass it to another component as a prop.

I am using pywebview as a React GUI for my Python application. The JavaScript modules are being bundled by webpack.

Error

Whenever I call setCourses() I am getting the following error and React shows a whitescreen.

Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development. See https://reactjs.org/docs/cross-origin-errors.html for more information.

What I have noticed/tried

  • when calling setCourses(["foo0", foo1", "foo2"]); this error is not thrown.
  • when calling setCourses(new Array(response)); it does not throw an error but somehow joins the Arrays elements to a new Array with the size of 1: ["foo0", "foo1", "foo2"] -> ["foo0,foo1,foo2"].
  • iterating over the Array and constructing a new one + checking that every element is a String
  • the error page of React mentioned using the cheap-module-source-map setting in case one is using webpack. Setting this didn't help either.

Similar questions (which didn't solve my poblem)

Simplified code snippet

As you can see below, I am fetching the data from the Python API in a useEffect hook and trying to set the state which shall rerender my component so that the child component <CourseList courses={courses} /> will display the courses.

export default function Dashboard(props) {
    // some props etc. were removed to keep this snippet simple
    
    // the state variable which causes issues
    const [courses, setCourses] = React.useState([]);
  
    // get Data from Python API
    React.useEffect(()=>{
        getData();
    }, []);
  
    /**
     * Gets the needed data (login status, courses, username) by calling the Python API
     */
    function getData() {
      window.pywebview.api.foo().then((foo) => {
        // do stuff
      }).then(() => {
        // fetch the courses from the Python API
        window.pywebview.api.getCourses().then((response) => {
          // try to update the state variable
          setCourses(response); // <------- throws the error
        }).catch((response) => {console.log(response);
      });
  
    }
  
    return (
      <Box>
        <MainAppBar />
        <Grid container spacing={0}>
            <Grid item>
              <MenuList />
            </Grid>
            <Grid item>
              <CourseList courses={courses} /> {/* passing the courses to the CourseList component */}
            </Grid>
            <FloatingSyncButton />
          </Grid>
        </Box>
    )
  }
  
  
  export function CourseList({ courses }) {
    
    // logic...
  
    return (
      <List>
      {/* trying to list each course item */}
        {courses.map((courseName) => {
          return (
            <ListItem
              key={courseName}
              disablePadding
            >
              <ListItemButton>
              <Checkbox/>
                <ListItemAvatar>
                  <Avatar>{courseName}</Avatar>
                </ListItemAvatar>
                <ListItemText primary={courseName} />
              </ListItemButton>
            </ListItem>
          );
        })}
      </List>
    );
  }

I would appreciate any help. Thank you!

flosommerfeld
  • 634
  • 2
  • 11
  • 23
  • It looks like courses isn't there when you try to render it. maybe wait for courses to have valid data. try this in the JSX ``` {courses.length > 0 && } ``` see what happens. when you console log the response is there any data? – Stefan T Nov 21 '21 at 18:26
  • Thanks for the help! Conditional rendering didn't solve the problem. Yep, the log shows data. – flosommerfeld Nov 21 '21 at 18:47
  • have u tried aysnc await instead of nesting the .then inside another .then? – Stefan T Nov 21 '21 at 19:10

1 Answers1

0

Could you try this?


const getData = async () => {
  try {
      const api = await window.pywebview.api.foo()
      // do some stuff with api

      // fetch the courses from the Python API
      const courseList =  await window.pywebview.api.getCourses()
      setCourses(courseList);
      }
  catch (e) {
console.log(error)
}
    }

Stefan T
  • 111
  • 8