extjs store.getById() fails - extjs

I'm trying to get an Associated Model (E.g. groups and associated users) from a store with:
Ext.each(this.getView().getSelection()[0].getAssociatedData().users,function(element){
var theuser = myStore.getById(element.id);
theuser.set('deactivated','true');
}
This works for the first 25 Users (id 1-25) however the store is filtered through a pagination plugin. In reason of the filtering with offset and limit the requested id isn't in the local store.
any idea on how to force the store to get the model from remote in case the id isn't available in the local cache?
Or is it anyhow possible to use the data from getAssociatedData, change something and write the record back through the writer proxy?
thx, I really appreciate your help!

The store's getById() method will only return the locally-available records.
If you want to retrieve a model, and you know the id already, you can simply do <model class>.load(id). (If the model is unknown, you can do myStore.getModel().load(id)
Note that the load method returns immediately, but it returns a stub - you'll want to use a callback to process the change to the deactivated field.
In ExtJS5, the Session support will help ensure that the models referred to in both the association store and your myStore object refer to the same model instance.

Related

in Entity Framework, DbSet.Local remains out of sync

This one is making me crasy : I have an EF model built upon a database that contains a table named Category with 6 rows in it.
I want to display this in a drop down list in WPF, so I need to bind it to the Categories.Local Observable collection.
The problem is that this observable collection never receives the content of the database table. My understanding is that the collection should get in sync with the database when performing a query or saving data with SaveChanges() So I ran the followin 2 tests :
Categories = _db.Categories.Local;
// test 1
Debug.WriteLine(_db.Categories.Count());
Debug.WriteLine(_db.Categories.Local.Count());
// test 2
_categories.Add(new Category() { CategoryName = "test" });
_db.SaveChanges();
Debug.WriteLine(_db.Categories.Count());
Debug.WriteLine(_db.Categories.Local.Count());
Debug.WriteLine(_categories.Count());
The test 1 shows 6 rows in the database, and 0 in local.
The test 2 shows 7 rows in the database, and 1 in local (both versions)
I also atempted to use _db.Category.Load() but as expected, it doesn't work because it is db first, not code first.
I also went through this page https://msdn.microsoft.com/en-us/library/jj574514(v=vs.113).aspx, created an object-based data source and linked my combo box to it, without success.
Does anyone know what I am doing wrong?
Thank you in advance for your help.
The DbSet<T> class is IQueryable<T>, hence DbSet<T>.Count() method maps to Queryable.Count<T> extension method, which in turn is translated to SQL query and returns the count of the records in the database table without loading anything into db context local cache.
While DbSet<T>.Local simply gives you access to the local cache. It contains the entities that you added as well as the ones being loaded by query that returns T instances (or other entities referencing T via navigation property). In order to fully load (populate) the local cache, you need to call Load:
_db.Categories.Load();
The Load is a custom extension method defined in QueryableExtensions class, so you need to include
using System.Data.Entity;
in order to get access to it (as well as to typed Include, XyzAsync and many other EF extension methods). The Load method is equivalent of ToList but without overhead of creating additional list.
Once you do that, the binding will work. Please note that the Local will not reflect changes made to the database through different DbContext instances or different applications/users.

Access data from a local model

Here is my problem, I hope some one can help me here, I'm developing a mobile app in qx.
In the application.js I call for a JSON in a server through the qx.store.json(url) that creates a model that I bind to a offline model to access the data offline in the app.
Everything good so far then when I try to access the data in the offline model it doesn't let me. The original JSON data is
array(timestamp=>time(),
userdata=>array(
array(userid=>0...),
array(userid=>1...)))
When I debug the JSON or the offline data with obj.getItem(1) it always returns me qx.data.model.userdata.
I'm trying to use the data inside the array of userdata to validate a user in a foreach statement but qx.data.model.userdata always returns undefined.
I try obj.getUserdata(), obj.getItem(1), obj being the offline model.
What am I doing wrong? It isn't a model a store for data, or it can only be used as binding data to an widget?
If the item at index 1 was an Array, obj.getItem(1) would return an instance of qx.data.Array. Since it returns an instance of qx.data.model.userdata, that means the model item is actually an object with a single property named "userdata" and you would access the value by calling obj.getItem(1).getUserdata().

How to identify a BackboneJS Model serverside

I'm just getting my head around BackboneJS, but one of the (many) things I'm still struggling with is how exactly the Models Sync up and relate to the serverside DB records.
For example, I have a Model "Dvd", now I change an attribute on the "Dvd" Model, the Name for example, and then I call save(), how exactly does the server side know what DB record to update? Does Backbone hold the DB row ID or something else?
Yes, typically you will set up your Backbone models so that they have database row IDs for any objects you're working with. When one of them is brand new on the client side and not yet saved to the server, it will either have a default or no ID, which doesn't matter since the server will be assigning the ID if and when the initial save transaction succeeds.
Upon saving or updating a model item, Backbone expects the server to reply with some JSON that includes any attributes that have changed since the save or update request was made. In the response to the initial save request, the server informs the client of a newly saved item's row ID (and you can also send along any other information you might need to pass to the client at the same time).
By default, the 'id' attribute of a model object is assumed to be its unique identifier, but backbone lets you change this if you're using a different identifier for the primary key. Just give your model an idAttribute parameter (see the docs for Backbone.Model.extend()) to do that.
Meanwhile, either the urlRoot parameter or a url function can be given to your models to characterize the urls that should be used to send the various ajax requests to the server for a given model.

Reloading an Ext.data.Store model?

I'm trying to fix some issue with an ExtJs website but not sure how to proceed. Basically, I have a form that loads an Ext.data.Store model. For new models, the model object initially doesn't have an ID. Once it's saved an ID is assigned to it by the webservice.
The problem is that this Ext.data.Store model is not being reloaded after saving, so it stays without an ID, which causes some problems later on.
So is there any way to force ExtJs to reload the store model after saving? I checked the documentation of Ext.data.Store but cannot see any "reload()" or "refresh()" method. Any suggestion?
You don't need to do anything special. ExtJs has a logic to replace models with phantom flag with the new copies received from the store after update procedure. Chec couple things:
Make sure you have correctly specified idProperty in the model. This is how ExtJs will detect whether record is new or not.
Make sure your store returns properly new/updated records in the response message.
Make sure your data reader properly parses these records in the response message.

How to generate model id's with Backbone.js

I am setting up the backbone sync mechanism and am a bit confused where to generate the id's for the models.
When I create a new model, should backbone be generating and setting the id, or am i supposed to implement an id generation method, or is there some sort of mechanism where I "PUT" the data to the server, which generates the id and returns a model with the id?
I'm providing a second answer to simplify the code you need to study to get the main points you're pondering about - the actual round about from model to server and how ids play their role.
Say you define a model - Let's go with Jurassic Park.
// Define your model
var Dinosaur = Backbone.Model.extend({
defaults: {
cavemanEater: undefined // Has one property, nom nom or not.
},
urlRoot: 'dino' // This urlRoot is where model can be saved or retrieved
});
var tRex = new Dinosaur({'cavemanEater':true});
You now have instantiated a dinosaur that is a meat eater. Roar.
console.log(tRex);
What you should notice is that in the properties of tRex, your model does not have an id. Instead, you will see a cID which you can think of as a temporary id that Backbone automatically assigns to your models. When a model doesn't have an id it is considered new. The concept of persisting a model (either to a database or local storage) is what allows you to go back to that resource after you've created it and do things like save (PUT) or destroy (DELETE). It would be hard to find that resource if you had no way to point directly at it again! In order to find that resource, your model needs an id, something it currently does not have.
So as the above answers have explained it is the job of your database (or localstorage, or some other solution) to provide Backbone with a resource id. Most of the time, this comes from the resource id itself, aka - the primary key id of your model in some table.
With my setup, I use PHP and mySQL. I would have a table called Dinosaur and each row would be a persistent representation of my dino model. So I'd have an id column (unique auto-incrementing int), and cavemanEater (bool).
The data communication flow happens like this.
You create a model.
The model is new so it only has a cID - no proper ID.
You save the model.
The json representation of your model is SENT to your server (POST)
Your server saves it to the table and gives it a resource id.
Your server SENDS BACK a json representation of the data {id:uniqueID}
Backbone RECEIVES this json representation with id
Backbone automagically updates your model with an id.
Here is what annotated code looks like.
CLIENT:
tRex.save();
// {'cavemanEater':true} is sent to my server
// It uses the urlRoot 'dino' as the URL to send. e.g. http://www.example.com/dino
SERVER:
// Is setup to accept POST requests on this specific ROUTE '/dino'
// Server parses the json into something it can work with, e.g. an associative array
// Server saves the data to the database. Our data has a new primary id of 1.
// Data is now persisted, and we use this state to get the new id of this dino.
$dinoArray = array('id'=>1, 'cavemanEater'=>true);
$dinoJSON = json_encode($dinoArray);
// Server does something to send $dinoJSON back.
CLIENT:
// If successful, receives this json with id and updates your model.
Now your tRex has an id = 1. Or should I say...
tRex.toJSON();
// RETURNS {'id':'1', 'cavemanEater':'true'}
Congrats. If you do this tRex.isNew() it will return false.
Backbone is smart. It knows to POST new models and PUT models that already have a resource id.
The next time you do this:
tRex.save();
Backbone will make a PUT request to the following URL.
http://www.example.com/dino/1
That is the default behavior by the way. But what you'll notice is that the URL is different than save. On the server you would need a route that accepts /dino/:id as opposed to /dino
It will use the /urlRoot/:id route pattern for your models by default unless you tweak it otherwise.
Unfortunately, dinosaurs are extinct.
tRex.destroy();
This will call... Can you guess? Yep. DELETE request to /dino/1.
Your server must distinguish between different requests to different routes in order for Backbone to work. There are several server side technologies that can do this.
Someone mentioned Sinatra if you're using Ruby. Like I said, I use PHP and I use SLIM PHP Framework. It is inspired by Sinatra so it's similar and I love it. The author writes some clean code. How these RESTful server implementations work is outside the scope of this discussion though.
I think this is the basic full travel of new Backbone data with no id, across the internets to your server where it generates, and sends back the resource id, to make your model live happily ever after. (Or destroy() not...)
I don't know if this is too beginner for you but hopefully it will help someone else who runs into this problem. Backbone is really fun to program with.
Other similar Answers:
Ways to save Backbone JS model data
or is there some sort of mechanism where I "PUT" the data to the server, which generates the id and returns a model with the id?
Kind of. When you call the save method of your model, backbone make a POST XHR and your application server should respond with JSON contains an id.
You can see an example here: http://addyosmani.com/blog/building-backbone-js-apps-with-ruby-sinatra-mongodb-and-haml/
Quoting from the link:
post '/api/:thing' do
# parse the post body of the content being posted, convert to a string, insert into
# the collection #thing and return the ObjectId as a string for reference
oid = DB.collection(params[:thing]).insert(JSON.parse(request.body.read.tos))
"{\"id\": \"#{oid.to_s}\"}"
end
If you don't know Ruby keep in mind what the last expression that is evaluated is automatically returned by the method.
What I understand from your question is that you want to have a collection with models that exist on the server. In order to get these models into the collection you'd have to add call 'fetch()' on the collection.
The url would be "/users" or something similar, that would have to return an array of objects with user data in there. Each item in the array would then be passed to UserCollection.add(). Well, actually it would be passed all at once, but you get the point.
After this your collection is populated. The url on the Model is meant for updating and saving the individual model. The url of the collection will also be used for creating models. Backbone's sync is RESTful, like Ruby on Rails. You can actually learn more about it on the documentation of Ruby on Rails:
http://guides.rubyonrails.org/routing.html
What you would generally do is have a different url for your model than for your controller. After populating your collection you have id's for each model in there because they came from the server.
Now when you add a new model based on user input you'd do something like this:
var HomeModel = Backbone.Model.extend({
defaults: {
lead: "not logged in",
},
url: 'test.php',
initialize: function(){
_.bindAll(this, 'handleSave', 'handleError');
// Save already knows if this.isNew.
this.save(undefined, {success: this.handleSave, error: this.handleError});
},
handleSave: function(model, response){
this.model.reset(model);
},
handleError: function(){
},
});
var HomeView = Backbone.View.extend({
initialize: function() {
_.bindAll(this, 'render');
this.model = new HomeModel();
this.model.bind("change", this.render);
},
el: 'div',
render: function() {
// Do things to render...
}
});
var homeView = new HomeView();
The example is from someone else's question I answered, I just add the relevant things.
The general idea is to save the model when it is created, if you need it somewhere else you can just move the code into a function of the model and call that based on events or anything else.

Resources