Hello everyone, nice to meet you all.
I am new to ember and I am trying to rewrite a react component to ember for learning porpoises. This is a resume of the component: ArtistPage.tsx
export default function ArtistPage(): JSX.Element {
// ......
const [wikipediaExtract, setWikipediaExtract] = React.useState<
WikipediaExtract
>();
React.useEffect(() => {
async function fetchWikipediaExtract() {
try {
const response = await fetch(
`https://musicbrainz.org/artist/${artistMBID}/wikipedia-extract`
);
const body = await response.json();
if (!response.ok) {
throw body?.message ?? response.statusText;
}
setWikipediaExtract(body.wikipediaExtract);
} catch (error) {
toast.error(error);
}
}
fetchReviews();
fetchWikipediaExtract();
}, [artistMBID]);
return (
{wikipediaExtract && (
<div className="wikipedia-extract">
<div
className="content"
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{
__html: sanitize(wikipediaExtract.content),
}}
/>
<a
className="btn btn-link pull-right"
href={wikipediaExtract.url}
target="_blank"
rel="noopener noreferrer"
>
Read on Wikipedia…
</a>
</div>
)}
);
}
This is my current ember component artist.js
export default class Artists extends DiscourseRoute{
async model(params) {
// Fetch the main artist data
const artistData = await this.store.find('artist', params.id);
// URLs for additional data
const wikipediaURL = `https://musicbrainz.org/artist/${params.id}/wikipedia-extract`;
// Fetch reviews and Wikipezzzdia extract concurrently
const wikipediaResponse = await fetch(wikipediaURL);
// Process responses
const wikipediaJson = await wikipediaResponse.json();
// Check for fetch errors
if (!wikipediaResponse.ok) throw new Error(wikipediaJson?.message || wikipediaResponse.statusText);
// Structure the model with all necessary data
return RSVP.hash({
artist: artistData,
wikipediaExtract: wikipediaJson.wikipediaExtract
});
}
}
with a synchonous aproach, I am fetching artist, which is the main model data and the wikipediaExtract in the model
hook
The cons with this approach is that I want to be able to render the template even if the wikipediaExtract
call fails.
For what I’ve researched, there are a couple of possible solutions:
1. Extend model:
export default DS.Model.extend({
wikipediaExtract: Ember.computed(function() {
const wikipediaURL = `https://musicbrainz.org/artist/${params.id}/wikipedia-extract`;
const wikipediaResponse = await fetch(wikipediaURL);
const wikipediaJson await wikipediaResponse.json();
return { wikipediaExtract: wikipediaJson.wikipediaExtract }
}
});
- With controllers
artist-controller.js
export default class ArtistsController extends Controller {
@service artistData;
@tracked wikipediaExtract;
@tracked isLoadingWikipediaExtract = false;
@action
async loadWikipediaExtract() {
const artistId = this.model.id;
this.isLoadingWikipediaExtract = true;
try {
const wikipediaURL = `https://musicbrainz.org/artist/${params.id}/wikipedia-extract`;
const wikipediaResponse = await fetch(wikipediaURL);
const wikipediaJson await wikipediaResponse.json();
this.wikipediaExtract = wikipediaJson.wikipediaExtract;
} catch (error) {
console.error('Error fetching additional data:', error);
} finally {
this.isLoadingWikipediaExtract = false;
}
}
}
3. afterModel hook
similar to the controller solution but using the afterModel hook
I understand that each solutions comes with i’ts own pros and cons and would like to know your take, considering the usecase. Thanks in advance
PD: for reference, here is the complete react component source code: ArtistPage