I'm new to JavaScript and React and am trying to move away from tutorials so have started making a simple app for my own learning benefit but have run into a roadblock with functions running asynchronously.
In onSearchSubmit
, there is a setState
which has the following in its callback:
this.findSalaryRangeMin(data.advertiser.id, data.teaser);
this.findSalaryRangeMax(data.advertiser.id, data.teaser);
How can I get these two functions above to run synchronously? findSalaryRangeMax
uses this.state.salaryLower
which is set in findSalaryRangeMin
, but the console.log
below reveals that findSalaryRangeMax
is firing before findSalaryRangeMin
has completed.
findSalaryRangeMax = (advertiserId, teaser) => {
console.log(`this.state.salaryLower: `, this.state.salaryLower);
// ... More code
};
I've read some resources which mention using promises, but I wasn't able to figure out how to apply it... I also am wondering whether it can be achieved with async
/await
.
Full(ish) Code: (I've removed some code for simplicity)
import React from "react";
import JobSearch from "../api/jobSearch"; // axios
import SearchBar from "./SearchBar";
class App extends React.Component {
state = {
jobTitle: "",
advertiser: "",
salaryLower: "",
salaryLowerTop: "",
salaryUpper: "",
salaryUpperTop: ""
};
findSalaryRangeMin = (advertiserId, teaser) => {
this.setState({ salaryLower: 0, salaryLowerTop: 200000 }, async () => {
let salaryLowerPrev;
for (var i = 0; i < 20; i++) {
const response = await JobSearch.get(
`http://localhost:3001/salary-range/${advertiserId}/${this.state.salaryLower}/${this.state.salaryLowerTop}/${teaser}`
);
console.log(response);
if (response.data.totalCount === 1) {
salaryLowerPrev = this.state.salaryLowerTop;
this.setState({
salaryLowerTop: Math.round(
(this.state.salaryLowerTop - this.state.salaryLower) / 2 +
this.state.salaryLower
)
});
} else {
this.setState(
{
salaryLowerTop: salaryLowerPrev
},
() => {
this.setState({
salaryLower: Math.round(
(this.state.salaryLowerTop - this.state.salaryLower) / 2 +
this.state.salaryLower
)
});
}
);
}
}
});
};
findSalaryRangeMax = (advertiserId, teaser) => {
console.log(`this.state.salaryLower: `, this.state.salaryLower);
// ... More code
};
onSearchSubmit = async term => {
const response = await JobSearch.get(
`http://localhost:3001/job-info/${term}`
);
if (response.data.totalCount === 1) {
const data = response.data.data[0];
this.setState(
{
jobTitle: data.title,
advertiser: data.advertiser.description
},
() => {
this.findSalaryRangeMin(data.advertiser.id, data.teaser);
this.findSalaryRangeMax(data.advertiser.id, data.teaser);
}
);
} else {
console.log("totalCount not equal to 1: ", response.data.totalCount);
}
};
render() {
return (
<div>
<SearchBar onSearchSubmit={this.onSearchSubmit} />
<hr />
<div>
Job Title: {this.state.jobTitle}
Advertiser: {this.state.advertiser}
Salary Lower Range: {this.state.salaryLower}
Salary Upper Range: {this.state.salaryUpper}
</div>
</div>
);
}
}
export default App;
To give some context, the app I'm trying to make, queries an API for a jobs listing site. The API response doesn't reveal a salary range for an individual job, but the salary can fairly accurately be determined by querying salary ranges.