Roundtrip in Breeze.Sharp ToDo sample project - breeze

I was able to install the Breeze.Sharp ToDo project. I noticed a behavior while adding a new todo item. When a new todo item is added, the server call SaveChanges is made by the client and the item is added successfully. The client again has to call the server by QueryAllTodos to get the latest list again. Why this round trip is necessary? Isn't the SaveChanges method supposed to merge the changes (the new list after the addition) with the client list to avoid this round trip again?

You are correct. There is no real need to requery after a save UNLESS there is some other server side "side-effect" ( say a trigger) that also changes the data. This code is just playing it safe.

Related

What is best practice on show temporary object and update it with original object in ios?

Asking this question is just to know the right way to update the existing contents after a user adds new content.
Here is the scenario:
Consider my app is like notes app, which can save the note in my server using API
The user tries to add new note by tapping create button. Then he hits the "Save" icon to save the typed note
Now, I need to call API (Say, addNotes API) to store the typed note in my server
I need to also resign the "Create Note" page in my app immediately
When the user see the notes list page, he will immediately expect the typed note
But as per theory, to update the notes list view, I need the API response
In practical, the resigning of "Create Note" page happens first. Because sending API, getting response, calling delegates, parsing content, creating responsible views/cells for the new item will take more time that resigning a view controller
Here comes the problem. For a smooth experience, most of us shows temporary object (which is stored locally) when the "Create Note" page resigns. After getting the API response, we will update the temporary object with original object
Consider I use NSManagedObject instead of just string like notes app. So I need to create a temporary object and should gave it to the list view from "Create" view.
Questions:
Should I create a temporary NSManagedObject? Or is it enough to create just a NSObject same like NSManagedObject?
With NSManagedObject/NSObject, I can show a temporary data in list view. After I get the API response, should I delete the temporary object and add the original object or should I update the temporary object? (In this case, I think that I need to create the temporary NSManagedObject object)
This may be a basic question, but eager to know the best practice from experts.
Thanks

Is it possible to change object A on the client, but modify object B on the server? [Default Breeze WebApi]

I'm trying to implement something like commands in my breeze app, but I miss "a bit of indirection", between the model on the client and my database/EF db context.
So here is the question:
How can I modify (create/update or delete) entity on the server, which is not one of the entities modified (created/updated/deleted) on the client?
For example:
To allow user password change create a new CmdNewPassword entity (with OldPassword and NewPassword fields) on the client, but on the server check that old password is correct and update User.PasswordHash and User.PasswordSalt.
or
If new Invoice entity was created on the client, create new LogEntry entity on the server to keep a log of user actions.
Save interception (http://www.breezejs.com/documentation/custom-efcontextprovider#SaveInterception) says that entities may be added or removed from the map returned by BeforeSaveEntities, but I don't think it is possible to add anything to this map, because EntityInfo's properties have internal setters.
Edit: May 8, 2013 - As of v 1.3.3, available on the Breeze website, there is a now a new public ContextProvider.CreateEntityInfo method that you should be able to call from within your BeforeSaveEntities method.
You are right, and you are on the right path with the idea of modifying the saveMap passed into the BeforeSaveEntities method. Currently, you can remove and modify entities from the map but you have no good way to add one. I will try to get this fixed in the next release.

With Breeze.js, Is There a Way to Create an Uninitialized Entity and Bind It to an "Add New" Form?

So far all of the examples that I have seen for adding a new entity would go through the following steps:
Create a bunch of "new-" variables that get bound to on screen controls.
When user wants to submit the addition, created an uninitialized new entity.
Copy "new-" variables to each member of the new entity one by one.
Push the new entity onto the manager's entity list.
Save changes.
Clear all of the "new-" variables.
This is problematic for many reasons. These "new-" variables have to be maintained in addition to the on screen controls. When server side entities change, they must be changed manually. This is time consuming and error prone.
I would like to be able to create an uninitialized new entity first, and bind it to on screen controls immediately, without using those variables with the "new-" prefix. When user wants to submit the addition, push the new entity onto the manager's entity list, and then save changes. Then bind the on screen controls immediately to a newly created uninitialized entity.
This way, we can avoid dealing with individual entity attributes in the view model, which would produce more robust code, and save a lot of time.
Right now, the metadata for creating a new entity is not available when the document becomes ready. If I download it, I have to deal with asynchronous completion before I can bind a new entity to on screen controls.
So my question is: is there a way to have the metadata downloaded with the initial HTML download so that I can create an uninitialized new entity without waiting, and bind it to on screen HTML controls immediately?
I'm not sure what means uninitialized new entity, but yes - you can create for example a new car like this:
var newCar = manager.metadataStore.getEntityType("Car").createEntity();
manager.addEntity(newCar);
Bind your controls to the newCar. To save the changes call manager.saveChanges();, to cancel call manager.rejectChanges();
To be able to work with entities breeze needs metadata. If you want, you can send metadata with the page itself. You can then use manager.importMetadata() to import it into the manager. The only problem is that you will need to write a small app that will generate the metadata string (during build) so that later it can be passed to importMetadata(). Take a look at MetadataStore Class API for more info.

Deleting Entities and its Navigation Properties

I have something like a Customer object with up to 50000 order in an ICollection<Orders>.
Assume the Custome being in the local cache, the orders not. How can i delete the Cutomer and all of its related orders without loading all of the Customer orders into the cache and marking them with setDeleted()?
What is the best practice here. I assume extending the public SaveResult SaveChanges(JObject saveBundle) method is the best way. Any other possibilities here on the client side like a flag delete_all_navigation_too()?
Thanks
I must suppose that you do not have and do not want cascade delete on your database. Personally, I'm "terrified" of deletes in general and try to avoid them. I prefer a soft delete (marking a record as inactive). But not everyone agrees or can follow suit
I would consider adding a Web API method (say "DeleteCustomerAndOrders") to your controller to do it. You can call any API method from your client, not just a Breeze method.
In recommending this, I'm assuming that this kind of thing is a relative rarity in your app. You don't need a general purpose deleter, a deleter that takes an array of parent object IDs, a deleter that will delete some child objects and not others, ... etc., etc.
Follow this path and you will have moved the problem from the client to the server. That's good: you didn't have to load the orders on the client. Now you have to get rid of them on the server. If you're using Entity Framework, you face the same challenge of deleting the orders without loading them. Check out Alex James' solution: Bulk-deleting in LINQ to Entities.
Simplest approach that I can come up with is to create a cascade delete constraint on the database so that when a customer is deleted all of its orders get deleted as well. Then simply delete the customer on the client and call 'SaveChanges'. In addition, since Breeze does not yet support client side 'cascaded' deletes ( we are considering this one), you will need to iterate over any client side orders that are already loaded and 'detach' them.

Ria Services - SubmitChanges() problem. Possible to limit to one change at a time?

I would like to submit a collection of entities one at a time.
There are 2 reasons for this:
- I'm uploading a lot of data and submitting more than one change exceeds the http limit for these transfers. (i don't want to change this limit)
- I want to see the progress of each item getting submitted.
Example: Suppose I have an album and each album has a collection of photos (entities).
If the user adds some photos, I want to upload one photo at a time and not the whole chunk at once.
If you'd like to Submit one change at a time, simply call SubmitChanges upon committing an edit, or adding or deleting an entity...
Typically in your UI if you have some sort of commit button, then tie that to do two things - both the local commit, and subsequent SubmitChanges.
Note you can also override ValidateChangeSet on your DomainService to ensure there is only one operation in the ChangeSet. This ensures clients don't inadvertently try to commit more than one change at a time...
SubmitChanges() will submit the changes in a changeset (all that have changed since you loaded it). I don't know how to modify it's behavior, but you could write your own update method in the service and pass in the object you want to update
Check out the riaservicesoverviewpreview.pdf at http://code.msdn.microsoft.com/RiaServices around page 50 for some info about the update.
Edit: I found this method yesterday while trying to do the same thing with WPF: link text. I used the idea of detaching and then attaching the entity (I'm using a single static global DataContext).

Resources