Search code examples
asp.net-mvcknockout.jsbreeze

Breeze.js: how to transform a Breeze entity to a plain JSON object


I have an entity instance created using the metadata coming from the server:

breeze.NamingConvention.camelCase.setAsDefault();

...

var applicationType = metadataStore.getEntityType('Application');
var application = applicationType.createEntity();

None of the objects in this particular model has circular dependencies.

After the user has made some changes to the corresponding object, I need to perform some custom validation on that entity, so I need to convert that object back to its JSON simple form and send it back to a validation Controller (ASP.NET MVC4).

The question is how to transform the entity to JSON such that:

  1. The resulting object reflects the naming conventions used in the server side.
  2. The object contains simple properties and not knockout observables.
  3. And does not contain any other additional property or function used internally by breeze.

I was expecting to find something like:

var json = application.toJS();

But such method does not exist. Using ko.toJS(application) also doesn't work because (1), (2) and (3) are not fulfilled.

I'm sure this should be trivially easy to do, but I just can't find anything even remotely related on the documentation.

UPDATE: You'll forgive me for the horrible hack, but because I'm in a hurry what I did that temporarily solved my problem was just exposing the unwrapEntities internal function of entityManager. I also changed the function definition a little bit (just to exclude that annoying entityAspect):

function unwrapEntities(entities, metadataStore, includeEntityAspect) {
    var rawEntities = entities.map(function(e) {
        var rawEntity = unwrapInstance(e);

        if (includeEntityAspect !== undefined && includeEntityAspect === false) {
            return rawEntity;
        }
        ...
    });
}

And because I have the entityManager available at all times in my services, I was able to extend my types definition to do something like the following:

function createApplicant(initialValues) {
    var applicant = applicantType.createEntity(initialValues);

    applicant.toJS = function () {
        var unwrappedEntities = entityManager.unwrapEntities([applicant], entityManager.metadataStore, false);
        return unwrappedEntities[0];
    };

    return applicant;
}

And that's precisely what I need:

var json = application.toJS();

Solution

  • This is a good idea! Could you please add it to the Breeze User Voice. It makes a lot of sense to expose the "unwrapping" of a Breeze entity.

    Just a small side note, the unwrap "hack" that you wrote may not work in a future version of Breeze because we are currently in process of refactoring some of this code, but I will try to expose a "cleaner" version as part of the Breeze api.