Building a simple search component


#1

Hi :slight_smile:

In my application I have to build a search component to search for articles via an EAN (European Article Number).

My model looks like the following:

/app/models/article.js
import DS from 'ember-data';

export default DS.Model.extend({
    name: DS.attr('string'),
    number: DS.attr('number')
});

My backend provides data at articles/8711500019974 or at articles?ean=8711500019974, but if I call only articles/ without any ean the server responses with an error.

I’ve got an route called ean and an component called ean-view. I use the ember-route-action-helper addon to use Closure Actions in my route.

/app/templates/ean.hbs
{{ean-view article=model findArticle=(route-action 'findArticle')

In my route I load the data and refresh it if the component needs new data like this:

/app/routes/ean.js
import Ember from 'ember';

export default Ember.Route.extend({
    model(ean) {
        if (typeof ean === "object){
            return {};
        } else {
            return this.get('store').findRecord('article', ean);
        }
    },

    actions: {
        findArticle(ean) {
            this.model(ean);
        }
    }
});

This is my components template:

/app/templates/components/ean-view.hbs
{{input value=ean}}
<button type="button" onclick={{action "findArticle"}}>Search</button>
{{article.name}}
{{article.number}}

My components controller looks like the following:

/app/components/ean-view.js
import Ember from 'ember';

export default Ember.Component.extend({
    actions: {
        findArticle() {
            this.get('findArticle')(this.get('ean'));
        }
    }
});

I think the main problem is that when my model updates in the route, the component does not get the new data, so my question is, how can I change this?

If you detect any errors or bad practices in my code, please tell me what to change :slight_smile:


#2

I’m to new to emberjs know how to solve your issue out the box, but I did read something in the docs that seems to address this: https://guides.emberjs.com/v2.7.0/object-model/observers/#toc_observers-and-asynchrony

Hopefully that helps.


#3

Newbie as well, but wouldn’t it be a bit easier to send the component action up to the route with this.sendAction() and the ean as parameter. And then have the route transition to itself with query string that has the ean. I can then set up the route to refresh the model on that query para!eter and perform the search in the model hook. There’s some info for such use of query parametes: https://guides.emberjs.com/v2.7.0/routing/query-params/#toc_opting-into-a-full-transition


#4

Yeah I tried this, but I did not manage to use this, thanks anyway :slight_smile:

Thank you very much, this works fine, also with my Closure Actions, so I don’t need to use the sendAction() method. I would also like to display errors, so do you know how to do this?


#5

Depends on the error type. What do you have in mind?


#6

If an error occurs, my server responses with an 422 - Unprocessable Entity and the following JSON:

{
    "errors": [
        {
            "detail": "No article with this EAN was found",
            "source": {
                "pointer": "data/attributes/name"
            }
        }
    ]
}

In my component I’m trying to display the errors like this:

/app/templates/components/ean-view.hbs
{{#each article.errors.name as |error|
    <p>{{error.message}}</p>
{{/each}}

But I think the reason for this is explained here: https://github.com/emberjs/data/issues/4474 , so I hope this gets fixed soon.


#7

I would have suggested something similar, so hopefully it gets fixed and does the trick for you.


#8

Yeah at first I thought I would do something wrong, but on an other model I use store.findRecord() and there the errors can be shown.

As I don’t know how long it takes until the bug is going to be fixed and I have to implement a mechanism to display errors now, does anybody of you has an alternative idea how to show the error messages?