I am building an application with pure javascript and Web Components. I also want to use the MVC Pattern, but now I have a problem with asynchronous calls from the model.
I am developing a meal-list
component. The data is coming from an API as JSON in the following format:
[
{
id: 1,
name: "Burger",
},
]
I want the controller to get the data from the model and send it to the view.
meals.js (Model)
export default {
get all() {
const url = 'http://localhost:8080/meals';
let speisekarte = [];
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
}).then(res => {
return res.json()
}).then(data => {
// This prints the result I want to use, but I can't return
console.log(data);
// This does not work
speisekarte = data;
// This also does not work
return data;
});
// is undefined.
return speisekarte;
},
}
This is how I tried to get the data from an API.
meal-list.component.js (Controller)
import Template from './meal-list.template.js'
import Meal from '../../../../data/meal.js'
export default class MealListComponent extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: 'open'});
// Should send the Data from the model to the View
this.shadowRoot.innerHTML = Template.render(Meal.all);
}
}
if (!customElements.get('mp-meal-list')) {
customElements.define('mp-meal-list', MealListComponent);
}
meal-list.template.js (View)
export default {
render(meals) {
return `${this.html(meals)}`;
},
html(meals) {
let content = `<h1>Speisekarte</h1>
<div class="container">`;
content += /* display the data from api with meals.forEach */
return content + '</div>';
},
}
As I mentioned in the comments, I have a problem in returning the async data from the model to the view. Either it is undefined when I try to return data;
or if I try to save the data into an array. I could also return the whole fetch()
method, but this returns a promise and I dont think the controller should handle the promise.
I already read the long thread in How do I return the response from an asynchronous call? but I could not relate it to my case.