skip to Main Content

I have a simple site which loads property-related data from a Danish national data provider, SDFI.
I am having issues passing down the right values from a mother component to a sub component.

My code looks like this:

My main component:

Search.js:

import { Container } from "react-bootstrap";
import { useState } from "react"; 
import { AsyncTypeahead } from "react-bootstrap-typeahead";
import ResultsDisplay from './ResultsDisplay';
const SEARCH_URI = "https://api.dataforsyningen.dk/autocomplete";

const AsyncSearch = () => {
    const [isLoading, setIsLoading] = useState(false);
    const [options, setOptions] = useState([]);
    const [found, setFound] = useState(false);
    const [hest, setHest] = useState([])
    const [grund, setGrund] = useState(0)

    const handleSearch = async (query) => {
        setIsLoading(true);    
        const response = await fetch(`${SEARCH_URI}?q=${query}&type=adresse`);
        const addresses = await response.json();

        setOptions(addresses);
        console.log(addresses);
        setIsLoading(false);
    };

    const handleChange = async (selected) => { 
      if (selected === undefined || selected.length == 0 )
      return;
    
      const s = selected[0] 
      const aga = s.data.adgangsadresseid;
      // console.log(`1. id = ${s.data.id}`)
      // console.log(`2. id = ${s.data.adgangsadresseid}`)
      // console.log(`id is ${selected[0].data.adgangsadresseid}`);

      let res;
      if (s.data.adgangsadresseid === undefined)
      {
        res = await fetch(`/bolig/${selected[0].data.id}`);  
      } else { 
        res = await fetch(`/bolig/${selected[0].data.adgangsadresseid}`);
      } 
      let searchResults = await res.json();
      setHest(searchResults);
      console.log(hest); 
      setFound(true);
     
      // Fetch boliggrundareal  
      const jordstykkeId = searchResults[0].jordstykke;
      const matRes = await fetch(`/grundareal/${jordstykkeId}`);
      const grund = await matRes.json();
      setGrund(grund.grundareal);
    }
  // Bypass client- side filtering by returning `true`. Results are already
  // filtered by the search endpoint, so no to do>it again.
  const filterBy = () => true; 

  return (
    <>      
      <AsyncTypeahead
        filterBy={filterBy}
        id="async-load"
        isLoading={isLoading}
        labelKey="forslagstekst"
        onChange={handleChange}
        minLength={3}
        onSearch={handleSearch}
        options={options}
        placeholder="Indtast adresse"
        renderMenuItemChildren={(opt) => (
          <>
            <span>{opt.tekst}</span>
          </>
        )}
        />    
        {hest.length > 0 && 
          <ResultsDisplay 
            grund={grund}
            hest={hest} 
            />
        }
    </>

    );
}

export default AsyncSearch;

Child component (ResultsDisplay.js)


import { useState } from "react"
import { Container } from 'react-bootstrap'; 

const ResultsDisplay = (hest, grund) => { 
    
    console.log(`grund = ${grund}`)
    return(
        <>
            <Container>
                <h2>Grund</h2>
                <p>{grund.grundareal}</p>
            </Container>
            {hest.hest.map((h, i) => {
                return (
                <Container>
                    <h2>Bygning</h2>
                    // ------ <snip> -----
                </Container>);
            })}
        </>
    );
}    
export default ResultsDisplay;

In the above example, the value of "grund" is never passed correctly from AsyncSearch to ResultsDisplay. If I debug the value of grund.grundareal inside AsyncSearch the value is correct (i.e. it’s an object with the property grundareal = some integer). However, after passing "grund" to ResultsDisplay, it shows up simply as an empty object.
What am I doing wrong? Could this be related to how the "grund" object is passed over to ResultsDisplay?

2

Answers


  1. There might be an issue that you are not getting the values right as expected.

    You should try the following ({hest, grund}) instead of (hest, grund)
    As you are already DE-structuring the parameters, this approach should work.

    More info

    Login or Signup to reply.
  2. You have to de-structure the props object. In react the first argument is always the props object.

    import { useState } from "react"
    import { Container } from 'react-bootstrap'; 
    
    const ResultsDisplay = ({hest, grund}) => { //HERE
        
        console.log(`grund = ${grund}`)
        return(
            <>
                <Container>
                    <h2>Grund</h2>
                    <p>{grund.grundareal}</p>
                </Container>
                {hest.hest.map((h, i) => {
                    return (
                    <Container>
                        <h2>Bygning</h2>
                        // ------ <snip> -----
                    </Container>);
                })}
            </>
        );
    }    
    
    export default ResultsDisplay;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search