Call api data in component

Hi everyone, I am new to ember.js and I have a question with a component. I am creating a component for infinite scroll and I need to make a call to the api. I have this code:

infite-scroll.js

import Ember from 'ember';

export default Ember.Component.extend({
    isLoading: true,
    model: '',
    page: 2,
    store: Ember.inject.service(),
    didInsertElement() {
        let self = this;
        let query = self.model.topics.query;
        let pages = self.model.topics.meta.pagination.pages;

        Ember.$(window).scroll(function () { 
            if (Ember.$(window).scrollTop() >= (Ember.$(document).height() - Ember.$(window).height()) - 1) {
                if(self.isLoading) {
                    if(self.page <= pages) {
                        query['page'] = self.page;
                        self.get('store').query('topic', query).then(function(data) {
                            self.page = self.page + 1;
                            self.model.topics.addObjects(data.get("content"));
                            if(self.page >= pages) {
                                Ember.$(window).unbind('scroll');
                                self.set("isLoading", false);
                            }
                        });
                    }
                }
            }
         });
    }
});

infinite-scroll.hbs

{{#if isLoading }}
    {{gettext "Please wait..."}}
{{/if}}

{{yield}}

call to component:

{{infinite-scroll model=model}}

My route:

import Ember from 'ember';

export default Ember.Route.extend({
    model(params) {
        return Ember.RSVP.hash({
            forum: this.get("store").find("forum", params.pk),
            topics: this.get("store").query("topic", {slug: params.slug}),
        });
    }
});

Is it good practice the way I did or is an antipattern?. I know there are libraries for this, but they did not work well and I decided to do it myself. It’s not that complicated.

Thanks!

I tend to fall in the less-than-dogmatic camp when it comes to the question of components fetching their own data. I do try to keep such activity in the route as much as possible, but sometimes we have components that the route doesn’t know of in advance.

In your case, I’d say your solution is clean and consise, which is the best pattern of all. For you to pull that off in the route, you would need to signal the route when scrolling events occurred then move the query calls in the event handler in the route. I don’t see the level of abstraction to be of benefit in this particular case.

2 Likes

Excellent, thanks Chris! :slight_smile: