lundi 5 août 2019

I need recomendations about emberjs nature

I'm working with emberjs during some time and now I want to redefine my understanding of ember's nature.

Question 1. Am I right that the route's model() hook is the best place to write asynchronous code (to get all needed data)? Should I try to place all my network requests (or at least most of them) inside routes' models?

Question 2. The component hooks have synchronous nature. Does that mean it's a bad desition to write async code inside hooks?

Say, I have async init() hook where some data is calculated and didRender() hook where I expect to use that data. When ember calls init() it returns Promise, so it's moved from a stack to a special queue and ember doesn't wait until event loop returns that code back to a stack. So ember runs next hooks, and when didRender() is being executed the init() hook may not be fulfilled and the expected data may not exist. Is it right?

Question 3. Services hooks should also be synchronous. Because when a service is injected inside a component and is used ember also doesn't wait until the async hook is fulfilled.

Say, I have a shopping cart service with products property. The products ids are stored in localstorage and I want to get those products from a server to set them into products property.

import Service from '@ember/service';
import { A } from '@ember/array';
import { inject as service } from '@ember/service';

export default Service.extend({
    store: service(),

    init(...args) {
        this._super(args);
        this.set('products', A());
    },

    async loadProducts() {
        const cartProducts = A();
        const savedCartProducts = localStorage.getItem('cartProducts');
        if (savedCartProducts) {
            const parsedSavedCartProducts = JSON.parse(savedCartProducts);
            const ids = Object.keys(parsedSavedCartProducts);
            if (ids.length > 0) {
                const products = await this.store.query('product', {id: Object.keys(parsedSavedCartProducts)});
                products.forEach(p => {
                    p.set('cartQuantity', Number(parsedSavedCartProducts[p.id].qty));
                    cartProducts.pushObject(p);
                });
            }
        }
        this.products.pushObjects(cartProducts);
    },
  ...
});


If I call loadProducts() from service's init() I can't use this.cart.products in controllers/application.js, for example. Because service is ready, but async init() is still executed. So, should I call it in routes/application.js model() hook?

Question 4. If there is some general component that doesn't refer to any route, but this component needs some data from a server. Where should I make async requests? Or computed properties and observers are the only solutions?

Thanks a lot.




Aucun commentaire:

Enregistrer un commentaire