user3002456
user3002456

Reputation: 25

Using the results from useEffect

I have two calls to two seperate APIs I want to create a third result that is a combination of the first two. However I cannot access the variables.

export default function AutoServices() {
  const [data, setData] = useState();
  const [a, setA] = useState();
  const [b, setB] = useState();
  const [C, setC] = useState();

  useEffect(() => {
    FetchCurrentPage(result => setData(result.content.default));
    FetchAutoServices(result => b(result.records));
    FetchSetAccel("/locationsinit", result => setA(result.serviceGroups));
    setC(AddDesc(a, b));
  }, []);


  function AddDesc(x, y) {
    var result = x;
    for (var i = 0; i < result.length; i++) {
        for(var j = 0; j < y.length; j++)
        {
            if(result[i].slug === y[j].iconclass)
            {
                Object.assign(result[i], {Desc: y.content.default.teaser});                
            }
        }      
    }
    return result;
  }  
  return (    
    <>
      {data && (
        <Helmet> ...........

The error in the browser is Cannot read property 'length' of undefined referring to the first line of the for statement I know that my code is returning json because when I inspect chrome I can see the json

Upvotes: 2

Views: 161

Answers (2)

Tim
Tim

Reputation: 1072

You are dealing with async code, so you'll have to wait on the first two to resolve. You can use Promise.all, and then do whatever with the result *potentially like:

useEffect(() => {
  FetchCurrentPage(result => result.content.default)
  const [a, b] = Promise.all([
    FetchAutoServices(result => result.records),
    FetchSetAccel("/locationsinit", result => result.serviceGroups);
  ]);
  setC(AddDesc(a, b));}, 
[]);

Upvotes: 0

Phishy
Phishy

Reputation: 79

State updates are asynchronous, which is why a is still undefined when you call AddDesc in the same useEffect closure. You could add a second useEffect with a and b as dependencies:

useEffect(() => {
  FetchCurrentPage(({ content }) => setData(content.default));
  FetchAutoServices(({ records }) => setB(records));
  FetchSetAccel("/locationsinit", ({ serviceGroups }) => setA(serviceGroups));
}, []);

useEffect(() => {
  if (a && b) setC(AddDesc(a, b));
}, [a, b]);

Upvotes: 1

Related Questions