Backbone.js - prevent PUT/POST on model.validate failure - javascript

Using the following as an example:
var Case = Backbone.Model.extend({
initialize: function(){
this.bind("error", function(model, error){
console.log(error)
});
},
url: function() {
return '/api/kase?id=' + this.get("id");
},
validate: function(attrs) {
return "An error";
}
});
In this case the validate method does not get called:
var kase = new Case();
kase.save();
In this case the validate method does not get called either:
var kase = new Case({subject: null});
kase.save();
In this case the validate method does get called, but the POST request is still made on save:
var kase = new Case();
kase.set("subject",null);
// An error
kase.save();
// POST http://localhost.local/api/kase?id=undefined 404 (Not Found)
Is this the expected behaviour? Am I missing something with regard to 'cancelling' the POST/PUT request when client side validation fails? Or should I be checking for a valid model before hitting the save method? (think the penny may have just dropped).
Any guidance would be most appreciated.

A set that fails won't update the model data while a call to save without parameters will post/put the current state of the model to the server (empty in your case). On the other hand, if you call your save method with the data to be validated, it will stop if the validation fails:
var kase = new Case();
kase.save({subject:null});
should log an error and stop before posting to the server.

Do you have code elsewhere that is calling save on the model?
Backbone does not call the server when setting a model's attributes; even if the validation fails.

Related

404 not found when sending post request to controller

I am calling a controller name batch_processor with the method parseFile defined.
I have a script as:
<script>
$(document).ready(function() {
$('#xmlfile').multi();
});
let parseFile = (update) => {
var xml = $('#xmlfile').val() || [],
payload = {xmlfiles: xml};
if(update) {
payload['update'] = 'y';
}
$.post('/batch_processor/parseFile/1', payload,
function(data, textStatus, xhr) {
var res = JSON.parse(data);
$('#xml').val(res.xml);
$('#parsed').val(JSON.stringify(res.parsed, null, '\t'));
$('#manifest').val(JSON.stringify(res.manifest, null, '\t'));
$('#report').val(JSON.stringify(res.report, null, '\t'));
}
);
};
So, when ParseFile Button is clicked this script is invoked. I have defined parseFile method inside batch_processor controller. Still I am getting
404 means the resource you are trying to access on server doesnt not exists
Why is there the "/1" in your url ? I think you can try to remove them. try again
check whether you have defined the parameter in function (parseFile($file_id)). For that check the same without parameter**(/batch_processor/parseFile)** . If it is working then it can be the issue with parameter.
If that doesn't work check whether you have defined htaccess to avoid index.php from url. if not add it.
Error 404 is thrown when URL you are trying to send your data to doesn't exist.
Check if /batch_processor/parseFile/1 doesn't have any typo in it (I can see mixed naming conventions - maybe that is it?) and if it has valid route to proper controller.

backbone fetch not updating the model

I am using a requirejs with backbone. The script runs without error but model.fetch() does not update the model. The two files for Backbone.js are:-
In main.js I have
'use strict';
require(['pageElements'],function(pageElements){
$( document ).ready(function() {
var country = new pageElements.country();
country.fetch({
success: function(e){
console.log(country.get('areaLevelZeroID')); // returns undefined
}
});
});
});
In pageElements.js I have
define(function() {
var country = Backbone.Model.extend({
url : 'resources/js/backBoneSandBox/countries.php',
parse: function(data){
newData = JSON.parse(data);
console.log(newData.areaLevelZeroID); // returns 1
return data;
}
});
return ( country );
});
Where the parse function is returning the correct value but not updating the model.
resources/js/backBoneSandBox/countries.php is tested and returns the jSON String
{"areaLevelZeroID":"1","areaLevelZeroName":"Afghanistan"}
I must be missing something really simple but I just can't see what. Thank you in advance for any advice you can offer.
In general flow is fetch - parse - set - success handler.
In your case you receive string response from the server, so you have to parse it to JSON, before calling set on the model. Thats why, you had to return newData;

Returning Status Code 400 Not Triggering Ajax OnFailure

I'm making an ajax post to an ASP.NET MVC action method and want to return an error as Json which should trigger the onFailure function. The code below works on my dev machine but as soon as I tried on our test environment the onFailure function is never hit.
I cannot use a solution that checks a boolean value in the onSuccess function to see whether a failure has occurred. I need a solution that will fire the onFailure function.
public static ActionResult GetModelErrorsInJson(this Controller controller)
{
controller.Response.StatusCode = (int)HttpStatusCode.BadRequest;
var errors = controller.ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => x.ErrorMessage);
var jsonErrors = JsonConvert.SerializeObject(errors);
return new JsonResult()
{
Data = jsonErrors
};
}
Apparently IIS was messing with my response and breaking things. I fixed it by setting the following property on the response.
controller.Response.TrySkipIisCustomErrors = true;

Update backbone model on click event and wait for response before changing location

I would like to update a backbone model when a user clicks a link. The code I have at the moment is:
$('a').on('click', function(){
// prevent default
event.preventDefault();
var id = $this.data('id');
// update backbone model
var click = new ClickModel({ "id": id });
var response = click.save();
// alert('testing');
if(response.status = 200)
{
return true;
}
});
However, the database is not being updated before the url has changed. If I add in the alert it works. What is the best way of preventing the location change before the model save has completed?
From the fine manual:
save model.save([attributes], [options])
[...]
save accepts success and error callbacks in the options hash, which are passed (model, response, options) and (model, xhr, options) as arguments, respectively.
So you can wait for the server to finish by saying:
click.save(null, {
success: function(model) {
// Do something interesting.
}
});
Of course save is still an AJAX call so your "something interesting" will happen later. You can force the save to be synchronous but that's an evil thing to do your users so I won't show you how.

Saving a Parse object from within a Backbone event

I'm using Backbone.js and Parse for persistence. I'm trying to save a parse object when a Backbone event fires, but it's not working. Here's my code (edited to remove unnecessary stuff):
Parse.initialize("abc123", "omgwtf");
var ListsView = Parse.View.extend({
events: {
"submit form": "newList"
},
newList: function() {
var GameScore = Parse.Object.extend("GameScore");
var gameScore = new GameScore();
gameScore.set("score", 2222);
gameScore.set("playerName", "Mike Hunt");
gameScore.set("cheatMode", true);
gameScore.save(null, {
success: function(gameScore) {
alert("success");
},
error: function(gameScore, error) {
alert("error: " + error.message);
}
});
}
});
My error alert is showing, but the error message is an empty string. The Parse object saves just fine when my saving code is at the same top-level scope as the Parse.initialize method. I'm in the process of learning Javascript, so any background on why this code isn't working would be awesome.
Based on your code it's hard to pinpoint the mistake, but here are some ideas:
Look at the response from the request: In Chrome, View->Developer->Developer Tools, click on the Network tab, and try submitting your form. You should see a new request entry come up (probably in red, since yours fails). Click on it and check the response to see if you get a useful error.
Check your settings on the GameScore table in your Data Browser: Click on More->Permissions and ensure that you have Create set to Public.

Categories

Resources