Breeze JS client with dynamic objects - breeze

I'm investigating using Breeze for client side caching and querying. Unfortunately the existing web service returns (JSON) objects that for a given type may have variable number and type of fields. They will all have a unique id and a few base fields, but for example a Person may have name, age and address say, and another Person may have name, birthdate and favoriteColor.
What each Person has is described by metadata sent embedded into each object (so each Person also has a metadata field).
Querying is obviously problematic here but assume for now that we will not be querying on any field that is not on all items of a given type.
We are using AngularJS too, in case that is relevant.
My question is, how would one handle this situation using Breeze? Would we be better off just using a simple object cache and "querying" simply by iterating over the cache with a predicate function?

Perhaps you should take a look on Jhon Papa's pluralsight video lecture for querying using client cache on pluralsight , which is a complete demonstration of breeze and angularJs. Also you can refer this

Related

How to form URL for different entity in Dynamics 365?

I am building up url for different entity in Dynamics 365 crm. I found this for crm 2011 but I want more elaborate solution than that.
Observed URL:
For Quote Entity: https:**[instance url]**.com/main.aspx?etc=1084&extraqs=&histKey=254156564&id=%7b[**GUID**]%7d&newWindow=true&pagetype=entityrecord&sitemappath=SFA%7cCollateral%7cnav_quotes#765575448
For Order Entity: https:**[instance url]**.com/main.aspx?etc=1088&extraqs=&histKey=653905533&id=%7b[**GUID**]%7d&newWindow=true&pagetype=entityrecord&sitemappath=SFA%7cCollateral%7cnav_orders#817364929
I created other url for other entities and observed the query parameter value of the url as like below:
1. etc is constant for different entity. eg. for quote(1084) and order(1088)
2. extraqs is empty.
3. histKey is variable for an entity. It is appearing in different value for a same entity record.
4. id is the unique identifier of a record (i have no question about this)
5. sitemappath is different for different entity.
Now I want to know about -
1. what is etc and why it remains same for a entity always?
2. what is histKey(why it gives random value every time) and sitemappath?
We are using these in our Dynamics 365 CRM application without issues. Read more
Simple record form using etc (entity type code):
https://myorg.crm.dynamics.com/main.aspx?etc=1&id=%7b[GUID]%7d&pagetype=entityrecord
Same record using etn (entity type name):
https://myorg.crm.dynamics.com/main.aspx?etn=account&id=%7b[GUID]%7d&pagetype=entityrecord
Same record in UCI:
https://myorg.crm.dynamics.com/apps/appname/main.aspx?etc=1&id=%7b[GUID]%7d&pagetype=entityrecord
Particular form using formid:
https://myorg.crm.dynamics.com/main.aspx?etc=1&id=%7b[GUID]%7d&pagetype=entityrecord&extraqs=formid%3d[formGUID]
sitemap can be ignored as the pagetype param will render the top navigation bar & histkey can also be ignored as its for internal platform/browser usage for previous/forward navigation. extraqs is any extra query string param you want to pass that pre-populate the form attribute.
https://myorg.crm.dynamics.com/main.aspx?etc=1&id=%7b[GUID]%7d&pagetype=entityrecord&extraqs=fullname%3DNew%20Contact
Documentation says:
Do not use the etc (entity type code) parameter that contains an integer code for the entity. This integer code varies for custom entities in different organizations
But if you are not creating a custom entity directly in any non-development environment, only the solution is being used to port the customizations across different environment then that should not be an issue.
To open a Particular Record for Account Entity, Where etn is Entity Schema name.
http://myorg.crm.dynamics.com/main.aspx?etn=account&pagetype=entityrecord&id=%7B91330924-802A-4B0D-A900-34FD9D790829%7D
For Example you have a Custom Entity let's call it Account Plan and your entity schema name is new_accountplan, so your url will be something like below
http://myorg.crm.dynamics.com/main.aspx?etn=new_accountplan&pagetype=entityrecord&id=%7B81440924-802A-4B0D-A900-34FD9D790829%7D
Similar way to open a particular Form for user to fill information
https://myorg.crm.dynamics.com/main.aspx?etc=1&id=%7b[GUID]%7d&pagetype=entityrecord&extraqs=formid%3d[formGUID]
You can use Power Pane Chrome addon which is a helper tool , help you to show entities urls

Breeze projection query from already-loaded entity

If I use breeze to load a partial entity:
var query = EntityQuery.from('material')
.select('Id, MaterialName, MaterialType, MaterialSubType')
.orderBy(orderBy.material);
return manager.executeQuery(query)
.then(querySucceeded)
.fail(queryFailed);
function querySucceeded(data) {
var list = partialMapper.mapDtosToEntities(
manager, data.results, entityNames.material, 'id');
if (materialsObservable) {
materialsObservable(list);
}
log('Retrieved Materials from remote data source',
data, true);
}
...and I also want to have another slightly different partial query from the same entity (maybe a few other fields for example) then I'm assuming that I need to do another separate query as those fields weren't retrieved in the first query?
OK, so what if I want to use the same fields retrieved in the first query (Id, Materialname, MaterialType, MaterialSubType) but I want to call those fields different names in the second query (Materialname becomes just "name", MaterialType becomes "masterType" and so on) then is it possible to clone the partial entity I already have in memory (assuming it is in memory?) and rename the fields or do I still need to do a completely separate query?
I think I would "union" the two cases into one projection if I could afford to do so. That would simplify things dramatically. But it's really important to understand the following point:
You do not need to turn query projection results into entities!
Backgound: the CCJS example
You probably learned about the projection-into-entities technique from the CCJS example in John Papa's superb PluralSight course "Single Page Apps JumpStart". CCJS uses this technique for a very specific reason: to simplify list update without making a trip to the server.
Consider the CCJS "Sessions List" which is populated by a projection query. John didn't have to turn the query results into entities. He could have bound directly to the projected results. Remember that Knockout happily binds to raw data values. The user never edits the sessions on that list directly. If displayed session values can't change, turning them into observable properties is a waste of CPU.
When you tap on a Session, you go to a Session view/edit screen with access to almost every property of the complete session entity. CCJS needs the full entity there so it looks for the full (not partial) session in cache and, if not found, loads the entity from the server. Even to this point there is no particular value in having previously converted the original projection results into (partial) session entities.
Now edit the Session - change the title - and save it. Return to the "Sessions List"
Question
How do you make sure that the updated title appears in the Sessions List?
If we bound the Sessions List HTML to the projection data objects, those objects are not entities. They're just objects. The entity you edited in the session view is not an object in the collection displayed in the Sessions List. Yes, there is a corresponding object in the list - one that has the same session id. But it is not the same object.
Choices
#1: Refresh the list from the server by reissuing the projection query. Bind directly to the projection data. Note that the data consist of raw JavaScript objects, not entities; they are not in the Breeze cache.
#2: Publish an event after saving the real session entity; the subscribing "Sessions List" ViewModel hears the event, extracts the changes, and updates its copy of the session in the list.
#3: Use the projection-into-entity technique so that you can use a session entity everywhere.
Pros and Cons
#1 is easy to implement. But it requires a server trip every time you enter the Sessions List view.
One of the CCJS design goals was that, once loaded, it should be able to operate entirely offline with zero access to the server. It should work crisply when connectivity is intermittent and poor.
CCJS is your always-ready guide to the conference. It tells you instantly what sessions are available, when and where so you can find the session you want, as you're walking the halls, and get there. If you've been to a tech conference or hotel you know that the wifi is generally awful and the app is almost useless if it only works when it has direct access to the server.
#1 is not well suited to the intended operating environment for CCJS.
The CCJS Jumpstart is part way down that "server independent" path; you'll see something much closer to a full offline implementation soon.
You'll also lose the ability to navigate to related entities. The Sessions List displays each session's track, timeslot and room. That's repetitive information found in the "lookup" reference entities. You'll either have to expand the projection to include this information in a "flattened" view of the session (fatter payload) or get clever on the client-side and patch in the track, timeslot and room data by hand (complexity).
#2 helps with offline/intermittent connectivity scenarios. Of course you'll have to set up the messaging system, establish a protocol about saved entities and teach the Sessions List to find and update the affected session projection object. That's not super difficult - the Breeze EntityManager publishes an event that may be sufficient - but it would take even more code.
#3 is good for "server independence", has a small projection payload, is super-easy, and is a cool demonstration of breeze. You have to manage the isPartial flag so you always know whether the session in cache is complete. That's not hard.
It could get more complicated if you needed multiple flavors of "partial entity" ... which seems to be where you are going. That was not an issue in CCJS.
John chose #3 for CCJS because it fit the application objectives.
That doesn't make it the right choice for every application. It may not be the right choice for you.
For example, if you always have a fast, low latency connection, then #1 may be your best choice. I really don't know.
I like the cast-to-entity approach myself because it is easy and works so well most of the time. I do think carefully about that choice before I make it.
Summary
You do not have to turn projection query results into entities
You can bind to projected data directly, without Knockout observable properties, if they are read-only
Make sure you have a good reason to convert projected data into (partial) entities.
CCJS has a good reason to convert projected query data into entities. Do you?

RhoMobile - locally storage and Rhom API

I am fairly new to using Rhomobile, however I am not fully understanding how the local storing works and how to use the Rhom API.
I've set up the RhoStudio and run the configurations.
What I am trying to achieve is basically have two data models (with property bags as default): one for wards, and one for patients so I can create patient and ward objects.
Eventually I would like to list the wards, and the patients that are assigned to the ward objects.
Can someone explain how I use the Rhom API to be able to achieve this?
I have ran a simulation so once I have something like: /app/Patient/{131199009368684.14}/show in the web inspector, so I am assuming that I will need to create an association of some sort.. And then filter it out with a group Query.
In my personal opinion using the RhoMobile Doc's are not helpful enough.
Many thanks if someone can give me a typical example.
Rhodes auto generates unique ids for each instance of a Module, when it is created. This property is called "object". "131199009368684.14" what you got is the "object" of a particular patient that you created. What you can do to link the patients to the ward is:-
Add an additional property to the Patient Model that stores the "object" of the Ward instance you want to link that particular patient to. Thus you will be able to list all the patients in a particular ward by running a find query on column that stores the object of the Ward in the Patient table, by supplying it the particular Ward's object.
Hope this is useful.

Nhibernate (and ORMs in General): work with Objects or ObjectIds?

This is something that has been pulling at me for a while. Consider a (MVC type) web application with an ORM (e.g. Nhiberate) as the data access layer.
On one hand - the OOP/Rich domain model hand - I feel I should be passing around (references to) the real objects I am talking about.
On the other hand - the DB/Web App hand - I feel that it is easier and more efficient just to pass the integer Ids of the objects rather than the object themselves.
Consider an ecommerce catalogue type application:
The user is logged in and navigates to a product page.
They post a comment.
The controller action tasked with persisting this comment has 3 pieces of information: a) The user id (from the auth cookie or wherever), b) The product id (probably from the querystring), and c) the comment text.
Now, what what is best practice here? Is it really worth inflating the user and product objects (e.g. by getting them from the repository, with all the DB work that entails) when we know that all they will be used for is so the ORM can read their IDs and set the appropriate foreign keys in the DB table that stores the comments?
What are peoples views on this? Perhaps web apps should be given a little more leway than other apps, due to their stateless nature? I imagine there will be 'it depends' answers, but maybe some people are purists about the issue.
This is a general question which probably is applicable to many platforms, but if giving examples I would prefer them to be ASP.NET MVC if possible.
Thank you.
NHibernate has the load operation (as opposed to doing a get) exactly for this reason.
session.Save(
new Comment
{
Text = commentTextFromScreen,
User = session.Load<User>(userID),
Product = session.Load<Product>(productID)
}
};
In the above example, you are telling NHibernate: I know these already exist in the database, so don't bother selecting them right now. NHibernate will return proxy objects for them and a select won't happen against the database as long as you don't attempt to access any properties on the objects.
For more info check out Ayende's blog post: The difference between Get, Load, and query by id.

Name on Check in QuickBooks SDK

I have a customer requirement to export the checks written in QuickBooks into a specific format because their bank allows fraud prevention by uploading a file and they verify the name on the check against what you give them before clearing it.
I looked at the QuickBooks SDK (we use the XML to communicate in general) and It references a field on the check called PayeeEntityRef with a FullName property, but typically in QuickBooks that data structure would indicate what the entity is called, not what appears on the check (Vendors have a NameOnCheck property, for example, which can be something other than their name).
Without coding up multiple test cases to demonstrate QuickBooks behavior here, does anyone have experience with getting the name as it was printed on the check? What is the best way to do it?
It's somewhat possible to get what you are wanting, but there are going to be some hiccups that you'll need to let you client know about. The main problem being that there's no way to retrieve the actual name printed on the check.
You would first need to query for the Checks/Bill Payment - Checks for the bank account. Then, using the PayeeEntityRef (I would use the ListID component) figure out which "List" the entity is on; Customer, Vendor, Employee, or Other. I don't know of any way to tell which list the PayeeEntityRef is from other than doing a query for each of the lists.
If the PayeeEntityRef is a Vendor or Employee, then you can retrieve the NameOnCheck value. The only thing you would need to keep in mind is that if the NameOnCheck has been modified AFTER the check was printed, the names will not match.
If the PayeeEntityRef is a Customer or Other name, then you have to do a little bit more. The value that QuickBooks uses for the printed name is based on what fields are filled out for the customer record. It first will use the CompanyName field if it is not null. Next, it will try to use the First/Middle/LastName fields, if they are not null. Finally, it will use the Name field as a last resort. Keep in mind that this is not the FullName field, just the Name field.
I haven't tested this with an "Other" name, as I have my clients try not to use that list, but I would imagine it's similar to how Customers work.

Resources