Ember.js update models from application controller - javascript

I need to update data every minute and on some specific events.
My idea is to create an action in ApplicationRoute, that would find the current router and evoke the model() method again.
But how can I access other routes from ApplicationRoute?
Maybe there are any other ideas to make it?

You don't have to reenvoke the model hook.
The matter is that most store data retrieval methods, for example, store.findAll() (ex store.find()) return live arrays. A live array will automatically update its content whenever new records appear in the store or existing records are removed.
So all you need is to repopulate the store.
A good place to periodically fetch the data is a service.
Also, you can enable/disable periodic data retrieval from within routes. Simply create a mixin that would enable data retrieval in the service when the route is visited and disable when the route is left.

Related

JAMStack - Small E-commerce store

Building a simple E-commerce store with Nuxt and Prismic.
I have this very simple action in my store:
async GET_ALL_CATEGORIES({commit}) {
// gets all the categories from prismic
// Set categories to the state
}
My question is, when I move around the application from / to /category1 to /category1/product1 should I be dispatching this action everytime?
Would one save this array of categories in localStorage?
Should I have an if block in my asyncData that checks for the categories state and if it is empty, dispatch the action, otherwise use whats in state?
How do the pros handle this situation?
Thank you!
It depends on how often you think your 'categories from prismic' would change. If not very often then you can save it to the store and then just read from the store.
Otherwise you may want to query your API etc on every page load, probably in mounted()
EDIT: You many also want to set an expiry date on the state so that it can pull in fresh data at intervals

data persistence across elements

suppose I want to have a data provider element for my user, like
<user-data-provider user-data="{{data}}"></user-data-provider>
which sends an ajax request and gets the logged in user.
Suppose I want to access my user data in different pages, and I add this tag to wherever I need, but the problem is, every time the browser sees this tag, makes an ajax again and I have to wait until data is fetched!
I know I can make a variable in my main page and pass it along child pages, but that seems like overkill to me !
how can I persist user data across different pages and part of my app?
thank you in advance
There are different ways to do this.
You can use use a monostate pattern
You can have one instance of your user-data-provider element in your root element or index.html and use iron-signals to transmit the data to all other elements that want to consume it
You can use iron-meta to have global state
Use an external state management framework (i.e. redux). There is a polymer wrapper for it: polymer-redux
I would recommend using an external state mangement framework such as redux.
Some of the solutions are shown here:
Polymer 1.0 Global Variables
I used pouchdb for my data store, and used polymer's predefined elements to work with it
now every time that I need data, I just use that component

How to update model using query parameters and partially reloading route's DOM tree

I have a route that has a form with some search fields (e.g. code, name, and so on) and a table that updates results while the user types something on these fields.
I have made all form fields bound to its respective query parameter on controller. So, when ember propagates the fields values to the URI, the parameters the route reloads the model making the table to be updated. So far so good.
But, there is a side effect on this design, when the user types Ember reloads the entire route's DOM tree making the user to lose the focus on the field.
So, I would like to know how I could make only the table with the results to be updated while the user continually types whatever he needs on the form fields.
They are all on the same route's HBS with some components.
One solution might be to split it into two routes:
One route that shows your input fields. This routes controller holds the variables for the input-binidings.
a subroute that handles the queryParams by listening to changes on the parent controller and shows the results accordingly.
For the subroutes controller you could do something like this:
needs: ['fieldscontroller'],
// or fieldscontroller: Ember.inject.controller() if your are on a newer Ember version
code: Ember.computed.alias('controllers.fieldscontroller.code'),
name: Ember.computed.alias('controllers.fieldscontroller.name'),
// or name: Ember.computed.alias('fieldscontroller.name') on newer Ember versions
This way, only your subroute (with the results) would reload on changes made in the parent route.

Store status between forms in AngularJS?

I am going to try to be as specific as I can. This is what I am trying to accomplish:
I want to be able to show a User, which kind of shoes fit its needs. The user will be shown 4 forms, one at a time.
My idea is to show a form, and once the user clicks 'Next', save that status and show the next form. After all forms have been filled, use those choices to fetch the API and return results to the User.
Here are my questions:
Where should I store the status of his choices? Cookie? Session?
How would I organize Angular in order to have all these forms that are shown one after the other? Any resources that I could use as an inspiration?
BTW, I am using Rails as a backend.
I have based my question on this tutorial: http://code.realcrowd.com/the-wonderful-wizard-of-angularjs/
I see that he uses saveState() on submit, but I am not sure where that function is defined.
Since the app is a angular SPA, you can use a angular service to store the state of the selection made by user. This state would persist until user explicitly refreshes the browser (F5).
Create a service like
angular.factory('shoeSelectionState',function() {
var states=[{selection:{}},{selection:{}},{selection:{}},{selection:{}}];
return states;
});
In your controller inject this service,
angular.controller('MyController', function(shoeSelectionState) {
$scope.states=shoeSelectionState;
});
and bind the states array to each form elements, something like
<input type='text' ng-model='states[0].selection.size' name='size'>
If you want to persist the data on page refresh try using sessionStorage instead of localStorage as it gets automatically cleared when user closes the tab. The service mentioned above can do the persistence of the content to storage.
You could use localStorage as #sumain-bogati suggested, but you could just as easily do this without any page reloads. What you will need is a container with a controller that will store the user's choices (i.e. the model) and then use ngShow or ngRoute to display each page. Here is some example code:
Plnkr example of three pages and a model
Instead of calling the fourth page, you would call a function which would initiate an $http call to your backend API to submit the model values.

Marionette Backbone Composite View update model data on collection changes

I have been using a Marionette Composite View to render to display a page that contains a table of data along with a serious of buttons which allows the user to action on the information.
An example would be a 'reload' button and a 'confirm all' button.
I have encountered a bug whereby repeatedly hitting 'reload' is causing duplicate items in the collection. I'm trying to take this back to basics and understand what is the recommended way of communicating model changes between both the model and the collection in a composite view.
Can someone help?
If you use a Marionette CollectionView or CompositeView they will re-render to reflect what is in your collection, therefore your collection must contain duplicate models.
What are you calling in your refresh method? It sounds like this is where the problem lies. If you want to refresh your collection to reflect what is on the server, you should call the fetch() method on the collection. Default behaviour is to merge the current collection and the data received from the server.
If this is still causing duplicates it could be an error with the data returned from the server - eg if IDs aren't included.
If you want to completely replace the current collection with the data returned from the server you can pass {reset: true} to the fetch call, but this isn't recommended as you will be completely re-rendering every row in the table every time you refresh.

Categories

Resources