Expand my Community achievements bar.

SOLVED

Same data used between two different components.

Avatar

Level 1

I am using two different components hitting the same API on an SPA page. I am typically making two calls as of now for the two different components but I would like to consolidate them into one single call. The critical part of this is that I cannot cache the data(request keeps changing as per the user entry) and the response can be used once for each component. How do I break it down?

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi, 

 

You should create a singleton for managing your API call and then use this in both components. Something like this:

Something like this:

class DataService {
    constructor() {
        this.fetchPromise = null;
    }

    async fetchData() {
        if (this.fetchPromise) {
            // If a fetch is already in progress, return the existing promise
            return this.fetchPromise;
        }

        // If no fetch is in progress, start a new fetch
        this.fetchPromise = (async () => {
            try {
                const response = await fetch('https://api.example.com/data');
                const data = await response.json();
                return data;
            } catch (error) {
                console.error('Error fetching data:', error);
                throw error;
            } finally {
                // Keep fetchPromise in place until refreshData is called
            }
        })();

        return this.fetchPromise;
    }

    refreshData() {
        this.fetchPromise = null; // Clear the cached promise
        return this.fetchData();  // Start a new fetch
    }
}

// Create a singleton instance
const dataService = new DataService();

export default dataService;

Then you will invoke like this:

import dataService from './DataService';

export async function initializeComponent1() {
    try {
        const data = await dataService.fetchData();
        console.log('Data for Component 1:', data);
    } catch (error) {
        console.error('Error initializing Component 1:', error);
    }
}

 

Note that I added a refreshData() method to be used at convenience.

 

Hope this helps.

 



Esteban Bustamante

View solution in original post

1 Reply

Avatar

Correct answer by
Community Advisor

Hi, 

 

You should create a singleton for managing your API call and then use this in both components. Something like this:

Something like this:

class DataService {
    constructor() {
        this.fetchPromise = null;
    }

    async fetchData() {
        if (this.fetchPromise) {
            // If a fetch is already in progress, return the existing promise
            return this.fetchPromise;
        }

        // If no fetch is in progress, start a new fetch
        this.fetchPromise = (async () => {
            try {
                const response = await fetch('https://api.example.com/data');
                const data = await response.json();
                return data;
            } catch (error) {
                console.error('Error fetching data:', error);
                throw error;
            } finally {
                // Keep fetchPromise in place until refreshData is called
            }
        })();

        return this.fetchPromise;
    }

    refreshData() {
        this.fetchPromise = null; // Clear the cached promise
        return this.fetchData();  // Start a new fetch
    }
}

// Create a singleton instance
const dataService = new DataService();

export default dataService;

Then you will invoke like this:

import dataService from './DataService';

export async function initializeComponent1() {
    try {
        const data = await dataService.fetchData();
        console.log('Data for Component 1:', data);
    } catch (error) {
        console.error('Error initializing Component 1:', error);
    }
}

 

Note that I added a refreshData() method to be used at convenience.

 

Hope this helps.

 



Esteban Bustamante