Note that there are some explanatory texts on larger screens.

plurals
  1. POBreezejs flips the EntityState from Added to Modified before Save
    text
    copied!<p>I am building a SPA per the guidance provided in John Papa's Jumpstart. When I create the model, it has </p> <p>modelObservable().entityAspect.entityState.isAdded() = true;</p> <p>I update the text, dropdown and modelObservable().entityAspect.entityState.isAdded() = false;</p> <p>in my Datacontext:</p> <pre><code> var createProject = function (position) { return manager.createEntity(entityNames.project, { positionId : position.id(), start : position.start(), memberId : position.memberId() }); }; </code></pre> <p>which is called from my add viewModel:</p> <pre><code> define(['services/datacontext', 'durandal/plugins/router', 'durandal/system', 'durandal/app', 'services/logger', 'services/uiService'], function (datacontext, router, system, app, logger, ui) { var model = ko.observable(); var position = ko.observable(); var hourTypes = ko.observableArray([]); var isSaving = ko.observable(false); // init var activate = function (routeData) { logger.log('Add View Activated', null, 'add', true); var positionId = parseInt(routeData.id); initLookups(); return datacontext.getPositionById(positionId, position).then(**createProject**); }; var initLookups = function () { logger.log('initLookups', null, 'add', true); hourTypes(datacontext.lookups.hourTypes); }; // state **var createProject = function () { return model(datacontext.createProject(position())); }** var addNewProject = function () { if (position == undefined || position().id() &lt; 1) { console.log('callback addNewProject'); setTimeout(function () { addNewProject(); }, 1000); } else { datacontext.addProject(position(), model); console.log(model().id()); return; } } var **save** = function () { isSaving(true); **datacontext.saveChanges()** .then(goToEditView).fin(complete); function complete() { isSaving(false); } function goToEditView() { isSaving(false); var url = '#/Projects/'; router.navigateTo(url + model().id()); } }; var vm = { activate: activate, hourTypes: hourTypes, isAdded: isAdded, model: model, save: save, title: 'Details View' }; return vm; }); </code></pre> <p>the html</p> <pre><code>&lt;section data-bind="with:model"&gt; &lt;h1 data-bind="text: name"&gt; &lt;i class="icon-asterisk" data-bind="visible: hasChanges" style="font-size: 30px;"&gt;&lt;/i&gt;&lt;/h1&gt; &lt;div class="errorPanel"&gt;&lt;/div&gt; &lt;div id="overview" class="project" &gt; &lt;div class="row"&gt; &lt;div class="span4"&gt; &lt;label class="requiredLabel"&gt;Name*&lt;/label&gt; &lt;input type="text" name="name" data-bind="value: name" style="width: 27em;" class="required" placeholder="Project Name" required validationMessage="Project Name required" /&gt;&lt;span class="k-invalid-msg" data-for="title"&gt;&lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span3"&gt;&lt;label class="requiredLabel"&gt;Start*&lt;/label&gt;&lt;/div&gt; &lt;div class="span3"&gt;&lt;label class="requiredLabel"&gt;End&lt;/label&gt;&lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span3"&gt;&lt;input name="start" data-bind="shortDate: start" class="date required" required="required" placeholder="mm/dd/yyyy" style=" width:142px"&gt;&lt;/div&gt; &lt;div class="span3"&gt;&lt;input name="end" data-bind="shortDate: end" class="date" placeholder="mm/dd/yyyy" style=" width:142px"&gt;&lt;span class="k-invalid-msg" data-for="end"&gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;br/&gt; &lt;div class="row"&gt; &lt;div class="span3"&gt;&lt;label for="hourType" class="requiredLabel"&gt;Measure As*&lt;/label&gt;&lt;/div&gt; &lt;div class="span2"&gt;&lt;label for="hoursPerWeek" class="requiredLabel"&gt;Hours/Week&lt;/label&gt;&lt;/div&gt; &lt;div class="span2"&gt;&lt;label for="totalHours" class="requiredLabel"&gt;Total Hours&lt;/label&gt;&lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span3"&gt; &lt;select id="hourType" data-bind="options: $parent.hourTypes, optionsText: 'name', value: hourType" required validationMessage="Measure As required"&gt;&lt;/select&gt;&lt;span class="k-invalid-msg" data-for="hourType"&gt;&lt;/span&gt; &lt;/div&gt; &lt;div class="span2"&gt; &lt;input name="hoursPerWeek" type="number" min="1" max="120" required="required" data-bind="value: hoursPerWeek, validationOptions: { errorElementClass: 'input-validation-error' }, enable: hourType().id() == 1" class="hours required"" style="width: 80px;" validationMessage="Hours required"&gt;&lt;span class="k-invalid-msg" data-for="projectHours"&gt;&lt;/span&gt; &lt;span class="k-invalid-msg" data-for="totalHours"&gt;&lt;/span&gt; &lt;/div&gt; &lt;div class="span2"&gt; &lt;input name="totalHours" type="number" min="40" max="2080" required="required" data-bind="value: totalHours, validationOptions: { errorElementClass: 'input-validation-error' }, enable: hourType().id() == 2" class="hours required"" style="width: 80px;" validationMessage="Hours required"&gt;&lt;span class="k-invalid-msg" data-for="projectHours"&gt;&lt;/span&gt; &lt;span class="k-invalid-msg" data-for="totalHours"&gt;&lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="row"&gt; &lt;div class="span4"&gt; &lt;label class="requiredLabel"&gt;Description*&lt;/label&gt;&lt;span class="k-invalid-msg" data-for="description"&gt;&lt;/span&gt;&lt;span id="posMinDesc" style="visibility:hidden"&gt;&lt;/span&gt; &lt;textarea id="description" name="description" style="height: 200px; width: 650px;" data-bind="value: description, enabled:true, click: $parent.clearDefaults" rows="4" cols="60" class="richTextEditor k-textbox" required validationMessage="Description required" &gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="button-bar"&gt; &lt;button class="btn btn-info" data-bind="click: $parent.goBack"&gt;&lt;i class="icon-hand-left"&gt;&lt;/i&gt; Back&lt;/button&gt; &lt;button class="btn btn-info" data-bind="click: $parent.save, enable: $parent.canSave"&gt;&lt;i class="icon-save"&gt;&lt;/i&gt; Save&lt;/button&gt; &lt;/div&gt; &lt;/section&gt; </code></pre> <p>The json breeze sends to my controller is this: </p> <p>{ "entities": [ { <strong>"Id": -1,</strong> "Description": "poi", "End": null, "Gauge": 0, "Score": 0, "HourTypeId": 1, "HoursPerWeek": 45, "HourlyRate": null, "TotalHours": null, "WeightedHours": 0, "CreditMinutes": 0, "TotalCompensation": null, "IsCurrent": false, "Name": "poi", "PositionId": 1, "MemberId": 1, "Start": "2011-09-01T00:00:00Z", "undefined": false, "entityAspect": { "entityTypeName": "Project:#SkillTraxx.Model", "defaultResourceName": "Projects", "entityState": "<strong>Modified</strong>", "originalValuesMap": { "Name": "", "HourTypeId": 0, "HoursPerWeek": null, "Description": "" }, "autoGeneratedKey": { "propertyName": "Id", "autoGeneratedKeyType": "Identity" } } } ], "saveOptions": {} }</p> <p>As you can see, the above is incorrect b/c state is "Modified" and the Id = -1. This throws an error server side. I suppose I could trap the DbUpdateConcurrencyException, unwind the JObject and change "Modified" to added, but that's got code smell all over it.</p> <p>If anyone can help me find the face-palm moment in all of this, I'm ready. Thanks for looking!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload