I'm sorry because this is going to be a long post, but I would really appreciate help. I have been trying to make it work, but with no luck.
I am making a call to the database to grab images, during this call I want the loader to be active. The loader is not showing up during the call (when I hard code it it works). An other problem is the <NoResults />
component. It is supposed to render when a query to the database comes back empty. However, this component is rendering while the api call is running.
TLDR I want a loader during the api call, but instead the <NoResults />
component is rendering and then the data that returned from the db is rendering.
Using mongodb, express, mobx, and react.
Media Store Mobx:
export class MediaStore {
@observable loading = true
@observable trending = []
@action setLoading = (bool) => { this.loading = bool }
@action getTrending = async (category, pageNum, input) => {
this.setLoading(true)
this.error = false
let cancel
axios({
method: 'GET',
url: `http://localhost:3001/media/trending?category=${category}&page=${pageNum}&input=${input}`,
cancelToken: new axios.CancelToken(c => cancel = c)
}).then(res => {
this.trending =
[...new Set([...this.trending, ...res.data.creators]
.map(JSON.stringify))].map(JSON.parse)
this.setHasMore(res.data.creators.length > 0)
this.setLoading(false)
}).catch(e => {
if (axios.isCancel(e)) return
this.error = true
})
return () => cancel
}
}
MediaCards Component:
const MediaCards = inject('userStore', 'mediaStore')(observer((props) => {
const ref = useCreators(props.mediaStore);
const location = useLocation()
const classes = useStyles()
const { isLoggedIn, favorites } = props.userStore;
const { trending, loading } = props.mediaStore;
const { media, header, mediaCard } =
location.pathname === '/dashboard' && (!isLoggedIn || !favorites.length)
? { media: [], header: 'basic', mediaCard: false }
: location.pathname === '/dashboard'
? { media: favorites, header: 'basic', mediaCard: true }
: { media: trending, header: 'explore', mediaCard: true }
const renderMediaCards = (media) => {
return media.map((data, i) => {
let isFavorite = favorites.some(f => data._id === f._id)
if (header === 'explore' && media.length === i + 1) {
return <MediaCard lastRef={ref} id={data._id} img={data.img} isFavorite={isFavorite} twitchName={data.twitch} key={data._id} />
}
return <MediaCard id={data._id} img={data.img} isFavorite={isFavorite} twitchName={data.twitch} key={Math.random()} />
})
}
return (
<>
<Header page={header} />
{header === 'explore' ? <CategoryBar /> : <Paper className={classes.paperTopMedia}></Paper>}
{mediaCard
? <Paper className={classes.paperMedia}>
<Grid container>
<GridList cellHeight={180} className={classes.rootMedia}>
{!trending.length && !loading && <NoResults />}
{!loading && renderMediaCards(media)}
{loading && <Loading />}
</GridList>
</Grid>
</Paper>
: <EmptyCard />
}
</>
)
}))