Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

176
Views
Storing data from Axios Promise for multiple uses

I have created an endpoint in express that handles get requests. From a react component, I make a get request to said endpoint using axios. I want to store the data in an object in my Component class so that it can be accessed at multiple times (onComponentDidLoad, multiple onClick event handlers, etc). Is there a way to store the data outside of the axios promise, and/or preserve the promise so that I can do multiple .then calls without the promise being fulfilled?

I have tried using setState(), returning the promise, and returning the actual data from the get request.

Here is what I have right now:

constructor {
  super();
  this.myData = [];
  
  this.getData = this.getData.bind(this);
  this.storeData = this.storeData.bind(this);
  this.showData = this.showData.bind(this);
}

// Store data
storeData = (data) => {this.myData.push(data)};

// Get data from API
getData() {
    axios
        .get('/someEndpoint')
        .then(response => {
            let body = response['data'];

            if(body) {
                this.storeData(body);
            }
        })
        .catch(function(error) {
            console.log(error);
        });
}

showData() {
    console.log(this.myData.length); // Always results in '0'
}

componentDidMount = () => {
    this.getData();   // Get data
    this.showData();   // Show Data
}
    
render() {
  return(
      <Button onClick={this.showData}> Show Data </Button>
  );
}

Edit I was incorrect in my question, storing the promise and then making multiple .then calls works. I had it formatted wrong when i tried it.

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

If you just store the promise locally and access it as a promise it should work fine.

getData() {
  // if request has already been made then just return the previous request.
  this.data = this.data || axios.get(url)
  .then( response => response.data)
  .catch(console.log)
  return this.data
}

showData() {
  this.getData().then(d => console.log('my data is', data));
}
about 4 years ago · Juan Pablo Isaza Report

0

This code won't quite work because you're attempting to show the data without waiting it to be resolved:

componentDidMount = () => {
    this.getData();
    this.showData();
}

As you hinted toward in your original post, you'll need to extract the data from the Promise and there's no way to do that in a synchronous manner. The first thing you can do is simply store the original Promise and access it when required - Promises can be then()ed multiple times:

class C extends React.Component {
  state = {
    promise: Promise.reject("not yet ready")
  };

  showData = async () => {
    // You can now re-use this.state.promise.
    // The caveat here is that you might potentially wait forever for a promise to resolve.
    console.log(await this.state.promise);
  }

  componentDidMount() {
    const t = fetchData();
    this.setState({ promise: t });
    // Take care not to re-assign here this.state.promise here, as otherwise
    // subsequent calls to t.then() will have the return value of showData() (undefined)
    // instead of the data you want.
    t.then(() => this.showData());
  }
  
  render() {
    const handleClick = () => {
      this.showData();
    };

    return <button onClick={handleClick}>Click Me</button>;
  }
}

Another approach would be to try to keep your component as synchronous as possible by limiting the asyncrony entirely to the fetchData() function, which may make your component a little easier to reason about:

class C extends React.Component {
  state = {
    status: "pending",
    data: undefined
  };

  async fetchData(abortSignal) {
    this.setState({ status: "pending" });
    try {
      const response = await fetch(..., { signal: abortSignal });
      const data = await response.json();
      this.setState({ data: data, status: "ok" });
    } catch (err) {
      this.setState({ error: err, status: "error" });
    } finally {
      this.setState({ status: "pending" });
    }
  }

  showData() {
    // Note how we now do not need to pollute showData() with asyncrony
    switch (this.state.status) {
      case "pending":
        ...
      case "ok":
        console.log(this.state.data);
      case "error":
        ...
    }
  }

  componentDidMount() {
    // Using an instance property is analogous to using a ref in React Hooks.
    // We don't want this to be state because we don't want the component to update when the abort controller changes.
    this.abortCtrl = new AbortController();
    this.fetchData(this.abortCtrl.signal);
  }

  componentDidUnmount() {
    this.abortCtrl.abort();
  }

  render() {
    return <button onClick={() => this.showData()}>Click Me</button>
  }
}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!