0

I've got a function that makes a call to my Node backend, and retrieves an array of objects. This function, named queryDatabase, listed below:

function queryDatabase(locationName, timeFrame) {
    const location = locationName.charAt(0).toUpperCase() + locationName.slice(1);
    return new Promise((resolve) => {
        Axios.get(`/api/measurements/${location}/${timeFrame}`)
            .then((resp) => {
                console.log('RESPONSE', resp);
                resolve(resp.data);
            });
    });
}

This function is called by yet another function, getAllGroupNames, that retrieves an object and gets all group names out of it. This function returns a promise, with an array of the list of group names that my front-end needs to render.

export default function (locationName) {
    const arrayOfGroupNames = [];
    return new Promise((resolve) => {
        queryDatabase('Pagodedreef', 'uur').then((data) => {
            data.forEach((measurement) => {
                measurement.groups.forEach((group) => {
                    if (!arrayOfGroupNames.includes(group.name)) {
                        arrayOfGroupNames.push(group.name);
                    }
                });
            });
            resolve(arrayOfGroupNames);
        });
    });
}

I feel the above code is correct. The problem, however, arises when a function in my front-end React code, calls getAllGroupNames and tries to iterate over the array to return a new Checkbox element for each value.

renderCheckboxes() {
    getAllGroupNames('Pagodedreef').then((array) => {
        return array.map((groupName, index) => (
            <div className="checkboxes" key={index.toString()}>
                <label htmlFor={groupName}>
                    <input
                        type="checkbox"
                        id={groupName}
                        value={groupName}
                        onChange={this.onCheckboxChange}
                        checked={this.props.selectedGroups.includes(groupName)}
                    />
                    {groupName}
                </label>
            </div>
        ));
    });
}

If I put a console.log() around the getAllGroupNames().then() function, it returns an unresolved promise. I can't figure out how I can, instead of returning a promise, return the elements that need to be rendered.

If I chain an additional .then() at the end of the previous then() and log the value of that - it lists the values that I do indeed need. But again, when I return those - it has no effect.

Thank you in advance for helping me.

4
  • Avoid the Promise constructor antipattern! Commented Jan 30, 2018 at 10:41
  • 1
    I feel the above code is correct. Your feelings are incorrect.. :) Commented Jan 30, 2018 at 10:42
  • A render method should never call a querydatabase method. Commented Jan 30, 2018 at 10:42
  • "how I can, instead of returning a promise, return the elements that need to be rendered." - you simply cannot. They'll only be available in the future. Commented Jan 30, 2018 at 10:42

1 Answer 1

1

Instead of creating a new Promise you can just return the result of db query. However, making a db call for a render method doesn't sound good for performance-wise point of view.

export default function (locationName) {
    return queryDatabase('Pagodedreef', 'uur').then((data) => {
        const arrayOfGroupNames = [];
        data.forEach((measurement) => {
            measurement.groups.forEach((group) => {
                if (!arrayOfGroupNames.includes(group.name)) {
                    arrayOfGroupNames.push(group.name);
                }
            });
        });
        return arrayOfGroupNames;
    });

}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for taking the time to reply. I rewrote the function as you described. However, inside the renderCheckboxes() method, the getAllGroupNames().then() still returns an unresolved promise. I don't quite understand how I need to rewrite that function to utilize the change we just made.
You have the same issue in db access function as well. Don't create promise while fetching data from db and return right after you recieve the data.
Okay, I've removed the new Promise from queryDatabase, and instead returned the resp.data from the .then() method that is attached to Axios.get(). The problem I'm encountering is that when I put a console.log() around the Axios.get().then() method, it returns an unresolved promise, instead of the resp.data.
Once you are inside the promise chain, you will always get that. You can only access the result of promise inside a then method, not around it.
Understood. That makes sense. But then how am I going to ensure my renderCheckboxes() gets the values (divs) that it needs?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.