There are a few issues here:
- The main one is that
this.schema.json() returns a promise (as you know from your console.log). Promises don't have a properties property, so you're passing undefined to Object.keys, which then gives you that error.
- You're also not checking for errors from
fetch, in two different ways: You're not checking .ok (which is such a common error I've posted about it on my anemic little blog), and you're not checking for promise rejection.
You're also doing some unnecessary promise nesting and could be overlapping your fetch calls more.
First, since it seems you often fetch JSON, I'd suggest giving yourself a utility function for it:
function fetchJSON(...args) {
return fetch(...args)
.then(response => {
if (!response.ok) {
throw new Error('HTTP error ' + response.status);
}
return response.json();
});
}
Notice the .ok check.
Then, also in the "break the problem into smaller pieces" category, I'd have a fetchSchema function:
function fetchSchema(url) {
return fetchJSON(url, {
headers: new Headers({
'Accept': 'application/schema+json'
})
});
}
Then, loadFromServer can use Promise.all and destructuring to run the operations in parallel:
// (I assume this is in a `class` or object initializer, as it doesn't have `function` in front of it)
loadFromServer(pageSize) {
Promise.all(
fetchJSON('http://localhost:8080/api/employees'),
fetchSchema('http://localhost:8080/api/profile/employees')
)
.then(([empResponse, schema]) => {
this.schema = schema;
this.setState({
employees: empResponse._embedded.employees,
attributes: Object.keys(schema.properties),
pageSize: pageSize,
links: empResponse._links
})
)
.catch(error => {
// Do something with the error
});
}
Note the .catch, since you're not returning the promise from loadFromServer. (If you want to buck errors up the chain, add return in front of Promise.all and move the .catch to calling code.)
Side note: Your code used
this.scheme = schema;
Note that the property on the left is scheme (with a final e) but the variable is schema (with a final a). I think you meant schema and so I've included that change in the above, but if the property is really supposed to be this.scheme, you'll want to adjust that. Or if you don't need that property for anything other than the code in loadFromServer, remove that line entirely.