Breeze / breeze.js.samples

Breeze JavaScript Client sample applications
MIT License
96 stars 85 forks source link

Using - SaveBundleToSaveMap #33

Open israelpereira opened 9 years ago

israelpereira commented 9 years ago

I Tried to use the SaveBundleToSaveMap but I think there is something wrong with this Class..

I call it from my Controller and I always get an "Object reference not set to an instance of an object." Exception..

For Example:

var x = SaveBundleToSaveMap.Convert(saveBundle);

Do you guys have any thoughts about this ?

israelpereira commented 9 years ago

I just found what is happening .

The main problem is because the JsonSerializer is not being initialized .

So is a little change on SaveBundleToSaveMap is necessary .

Call the method " InitializeSaveState " of the ContextProvider to initialize the JsonSerializer and get the SaveWorkState Instance and after que call the method BeforeSave to get the SaveMap .

Code:

        /// <summary>
        /// Convert a saveBundle into a SaveMap
        /// </summary>
        public static Dictionary<Type, List<EntityInfo>> Convert(JObject saveBundle)
        {
            var provider = new SaveBundleToSaveMap();

            provider.InitializeSaveState(saveBundle);

            provider.SaveWorkState.BeforeSave();

            return provider.SaveWorkState.SaveMap;
        }

Thanks !

wardbell commented 9 years ago

What is the context of this issue? Which sample? Is there an action item for Breeze? Or is this issue closed?

israelpereira commented 9 years ago

Hi,

Sorry,

SaveBundleToSaveMap is a Class in DocCode sample, inside the "DocCode.DataAccess.EF" project.

It is a demonstration of technique to convert a saveBundle into a SaveMap, I used it because I don't want to use a ContextProvider to handle my changesets saves.

When I tried it, It was throwing an exception every time. But I found the error and now it is working fine.

israelpereira commented 9 years ago

I think is necessary you guys update the sample code.. maybe using the same solution

wardbell commented 9 years ago

Holy Smokes!

I have no idea how that got published. We have no example of its use ... not even a test. It must have been the beginning of an answer to a question ... and never got past that. I don't know how. Weird. And here you are, actually trying to use it!

How did you find this thing anyway? It's not documented as far as I know.

In any event, you are clearly correct. For it bombed immediately as soon as I stuck it into a controller. So I fixed it as you suggested.

Then I noticed that it was calling BeforeSaveEntity and BeforeSaveEntities without giving you a chance to specify them. That didn't feel right. So I extended the Convert call with two optional function parameters that let you specify those delegates.

Notice that I'm avoiding giving you the provider itself. It really isn't supposed to be a provider that you call. It's just a helper to get the save map. But maybe you'd like to use our BeforeSaveEntity and BeforeSaveEntities interceptors rather than reason over the save map yourself. So I added this extension.

Here's what it looks like now:

    /// <summary>
    /// Convert a saveBundle into a SaveMap
    /// </summary>
    /// <param name="saveBundle">JSON object from client describing batch save</param>
    /// <param name="beforeSaveEntity">
    ///   optional function to evaluate each entity individually before it is saved.
    /// </param>
    /// <param name="beforeSaveEntities">
    ///   optional function to evaluate the entire collection of entities before they are saved.
    /// </param>
    public static Dictionary<Type, List<EntityInfo>> Convert(
      JObject saveBundle,
      Func<EntityInfo, bool> beforeSaveEntity = null,
      Func<Dictionary<Type, List<EntityInfo>>, Dictionary<Type, List<EntityInfo>>> beforeSaveEntities = null)
    {
      var provider = new SaveBundleToSaveMap
      {
        BeforeSaveEntityDelegate   = beforeSaveEntity,
        BeforeSaveEntitiesDelegate = beforeSaveEntities
      };
      provider.InitializeSaveState(saveBundle);
      provider.SaveWorkState.BeforeSave();
      return provider.SaveWorkState.SaveMap;
    }

I made sure that it worked (as in appears to return a valid save map), with and without interceptors.

I pushed it to the repo in this revised state (SHA: b473853). But I don't have time to do anything with it now and I deleted my experiments.

Good luck with it. I'll close this ticket when you say it's OK and give me some background on your use case.

I'll close it also if I don't hear from you in a while. But I'd rather hear :-)

Thanks for the help.

israelpereira commented 9 years ago

Thanks for your help, I appreciate it.

I found this because I need use breeze change-set saves with another library (MemberShipReboot) that already have its own methods to save data, this methods have validation logics and events, so dont't make sense I implement another save logic.

So I use BreezeJs to manage the MB entities too but when user clicks on Save.. I need to avoid the Default breeze SaveChanges.. so I was looking for a workaround, I tried so many diferent ways untill I found this Class in DocCode Sample... and Now I'm using it to get the Entities and Save it.

I'm studying another Breeze samples concepts too, like EntitySaveMapper... and things can change.. I still in dev process yet...

When I finish this work I will tell you what I did.. will be good know your thoughts.