0

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 />
            }
        </>
    )
}))
Amelia W
  • 105
  • 1
  • 9
  • Your code looks fine on the first glance. Do you have some warning or errors in console? Are you using latest version of react and mobx? Do you have batching enabled? https://github.com/mobxjs/mobx-react-lite#observer-batching – Danila Sep 07 '20 at 19:29
  • Yeah I have done all of that. No warnings or errors. The 'trending' starts as an empty array so it renders the first until it comes back from the db with the full 'trending' list. I want it to have the loader until it comes back from the db with results or comes back empty. – Amelia W Sep 07 '20 at 19:41
  • Well, that's really weird then. Maybe it's something with `useCreators` hook, you pass mediaStore there, maybe it somehow modifies it? Can't think about anything else without sandbox reproduction. – Danila Sep 08 '20 at 08:27

0 Answers0