lundi 1 février 2016

Ember component libraries

I've come across a few Ember component libraries but don't see much activity in their repositories. This is raising some doubt as to whether I should use one in a brand new project.

Are people still using component libraries in new [Ember CLI] projects?

Example component libraries I've found:

Any experience with any of these lately? Any new kids on the block?

Or are you creating your own components as required?




best practice for unit testing Ember.js util with dependent util

I have an Ember util that I want to unit test. It uses another util.

// utils/util-1.js
import util-2 from './util-2';

export default util1() {
  util2();
}

I want to somehow mock the referenced util. Since it's not an Ember.Object, I can't take advantage of the service injecting system. I'm familiar with node require mocking, but I don't think I can use that here. The best I can come up with is:

// utils/util-1.js
export default util1(util2) {
  util2();
}

Anyone have anything better to share?




Refresh model with new params

I have a model that calls a query on my store. When something happens that causes the desired model to be a different query, I need to reload the data on the active route by firing the same query just with different param values.

To illustrate, when I come to my items route it fires a query that looks like this

return this.store.query('item',{auction_id: this.get('localStorage.user.user_active_auction'),user_id:this.get('localStorage.user.user_id')}).then((result)=>{
        if(result){
        return result;
        } else {
            this.get('notification').notify({message: "An error occurred trying to get items.",success:false});
            this.transitionTo('index');
        }
    });

The localStorage pieces are from a service. When the .user property of the service changes, I need to reload this query with the new .user_active_auction and .user_id values so new data gets placed in the template. (and thusly replaced what was there)

Can't seem to find how to do this as the .refresh() method reloads the cached url it used before rather than creating a new one. Not sure if maybe there is an adapter/serializer method I can implement that will allow me to tell it not to use the cached one?




EmberJS, understanding DS Model life cycle

I am trying to monitor the state changes on my DS Models.

I have found interesting flags in the documentation:

And they work properly in the templates, I can play with the {{#if model.isLoading}}Is Loading{{/if}}, for example.

But what is very disturbing is that the observers in these flags have a very random behavior. For example I have found that the observer over the flat isSaving doesn't work at all. But the observer over the flag isReloading works perfectly.

Here I have a full example of what I'm have tried until now. I have included this Mixin into my Model:

// app/models/mixins/loading-monitoring
import Ember from 'ember';

export default Ember.Mixin.create({
  isReloadingDidChange: Ember.observer('isReloading', function() {
    console.log('LOG: isReloadingDidChange', this.get('id'), this.get('isReloading'));
  }),

  isSavingDidChange: Ember.observer('isSaving', function() {
    console.log('LOG: isSavingDidChange', this.get('id'), this.get('isSaving'));
  }),

  isLoadingDidChange: Ember.observer('isLoading', function() {
    console.log('LOG: isLoadingDidChange', this.get('id'), this.get('isLoading'));
  }),

  isLoadedDidChange: Ember.observer('isLoaded', function() {
    console.log('LOG: isLoadedDidChange', this.get('id'), this.get('isLoaded'));
  }),

  onInit: Ember.on('init', function() {
    console.log('LOG: init', this.get('id'));
  }),

  onDidLoad: Ember.on('didLoad', function() {
    console.log('LOG: onDidLoad', this.get('id'));
  }),
});

And I try to invoke all these observers but only some ones are triggered:

> $E.toString()
  "<reports-dashboard-client-app@route:application::ember1553>"
> var report; $E.store.findRecord('report', 14).then(function(r) { report = r });
  Promise {_id: 438, _label: undefined, _state: undefined, _result: undefined, _subscribers: Array[0]}
  LOG: init 14
  XHR finished loading: GET "http://ift.tt/20CkzRq".
  LOG: onDidLoad 14
> report.toString()
  "<reports-dashboard-client-app@model:report::ember1554:14>"
> report.get('title')
  "new title"
> report.set('title', 'title modified')
  "title modified"
> report.save()
  Class {__ember1453996199577: null, __ember_meta__: Meta}
  XHR finished loading: PUT "http://ift.tt/20CkzRq".send 
> report.reload()
  LOG: isReloadingDidChange 14 true
  Class {__ember1453996199577: null, __ember_meta__: Meta}
  XHR finished loading: GET "http://ift.tt/20CkzRq".send
  LOG: isReloadingDidChange 14 false

What am I missing?




Ember 2.0 How can I make template and route talk to each other?

I am teaching myself Ember-cli and am trying to build a simple application, which fetches results when user searches for a term. I am stuck at the first level, As of now am passing a hardcoded query search term, I am getting the ajax result just fine, but I am not sure how to "pass" that to the template

This is my hbs code /app/templates/product-search.hbs

hello {{!-- just for testing --}}

<ul>
    {{#each item in result.content}} {{!-- even tried looping over result --}}
        <li>Product Info: {{item.id}}</li>
    {{/each}}
</ul>

This is the route file: /app/routes/product-search.js

import Ember from 'ember';

export default Ember.Route.extend({
    model: function(params){
        var term = 'random';
        var fetchURL = 'http://ift.tt/20CkzRm'+term;
        var result = [];
         $.ajax({
          url: fetchURL,
          dataType: 'jsonp',
          success: function(response){
            result.set('content', response.results);
           }
        });
        console.log("Search Results In Model: ");
        console.log(result);
        return result;
    }
});

This is what I am getting in console enter image description here

I am not sure how best to process the result set to be able to display it. Also I don't even know how to start the second piece, where in ideally I would want the search term to be a user input, by a text box, how would I send that back to the route?

Any help is appreciated, I've been stuck with this for a couple hours now.




Reasons a request would not be handled in Pretender

I have an xhr request in a custom authenticator using ember-simple-auth that doesn't get handled by pretender in tests. All of my other api calls get handled with no problems. No hooks for this request get called including unhandledRequest. The result is simply a 404 which causes tests to intermittently fail due to the 404 sometimes taking up to 3 seconds.

Any ideas about what might be causing this would be greatly appreciated.




should we communicate with component via actions or data

I am confused about what is better approach, should we prefer to communicate between components, components/controllers via data or actions more?

Here is an example: I have a file uploader component (wrapping the jquery plugin) and the way I have the component setup is like this:

1) the controller that contains the file uploader component defines a property via which two entities are going to share information about the file being uploaded

//some controller template
//where uploadedFiles is a property of the context controller
{{file-uploader uploadedFiles=uploadedFiles}}

2) this property is passed to the component and the component populates it with errors/progress etc as we initiate the upload. The structure of this data object looks like:

{
   'file': file object we get from plugin
   'errors': [],
   'progress':10,
   .... 
}

This component also does some basic file validation such as file type and size. When these errors happen, we populate the data object with errors. Now I am debating - should I have an action that gets triggered every time these custom validations fails, or is it ok to have an observer in the controller to inspect the data objects and then trigger whatever action it needs to.

I am leaning more towards communicating things via data itself because it keeps the interface of communication cleaner, but I also understand it cost an overhead of observers.

Passing actions on the other hand avoids having observers but I don't fully agree with it because then we might have 10 other situations where we might feel like passing "action" is the right choice and then pollute the component code(when it can be communicated via data).

I do agree that in certain cases we must have to pass actions, but given the choice that things can be communicated via bound data, is action the better choice?

Thanks.