I have a page developed using backbone, handlebar and _.js. While fetching the model (as a normal http jsonp callback request), i do set options.error and options.success. The success callback gets called properly. However, to simulate the network down scenario, when i disable the network adapter in my PC (from control panel) and trigger the call again, the error callback is not getting called.
Could anyone please suggest if I am doing anything wrong?
Thanks and Best Regards,
V. Vasanth
Need look at the code to find out what's the problem. If you put callbacks to fetch method that should be right:
model.fetch({
success:function()
{
},
error:function()
{
}
});
If you override model sync method it could be like this:
sync:function(method, model, options)
{
$.ajax({
url:"your_url",
// some other configs
success:function(data)
{
options.success(data);
}
error:function()
{
options.error();
}
})
}
Related
We're building a node.js application using Express, but are separating our layers. So the browser is running pure jQuery and javascript, the web server and application server are Node.js and Express. We're using REST APIs between them all.
We're using jQuery 1.10.2
Since the application server cannot be open to the public, the browser must make API calls to the web server, which manages making the call to the application server and returning the results. Here is what that looks like...
// Proxy all other API calls to the backend server
var request = require('request');
app.all('/api/*', function (req, res) {
var targeturl = apihost+req.originalUrl;
console.log("Proxy: "+targeturl);
request({
url: targeturl,
method: req.method,
json: req.body
}, function (error, response, data) {
if(error) {
res.send(error);
res.end();
} else {
console.log("SUCCESS...");
console.log(data);
res.send(data);
res.end();
}
});
});
Our data is a two-level hierarchy of Flows and one or more child Milestones on each Flow. When someone clicks the Save link on our page to save a Flow and its Milestones, the Javascript pulls the Flow data from the page, then makes an AJAX call to save the Flow information first, then waits for the "done()" handler before pulling the Milestone information from the page and making a second AJAX call to save that data. Here is the saveFlow() function executed in the browser...
function saveFlow(organization_id, user_id, flow_id) {
var name = $('#Name').val();
var purpose = $('#Purpose').val();
console.log("Trying to save flow: " + flow_id);
if (name && name.length > 0) {
$.ajax({
url: "/api/flow",
type: 'POST',
datatype: 'json',
data: {
flow_id: flow_id,
name: name,
purpose: purpose,
organization_id: organization_id,
user_id: user_id,
timestamp: (new Date())
}
})
.fail(function (error) {
console.log("Could not save the flow: " + error.message);
})
.done(function (flow) {
console.log("Saving milestones for flow "+flow.id+" ["+flow_id+"]");
saveMilestones(flow.id);
});
} else {
console.log("Refusing to save a flow that has no name");
}
}
The proxy code shows me that this call succeeded...
SUCCESS...
{ success: true,
message: 'Flow Updated!',
id: '56de8e346d229b492a0954f9' }
But the proxy code also demonstrates that the next API call never takes place. Moreover, the log statement in the Done block is never executed, nor are any log statements placed inside the saveMilestones() function.
Clearly, the .done() handler is never being called in this case. I use the done() handler in other parts of my code and it works. I've compared the code but don't see any differences. The proxy code we're using is driving every other API call made from our pages successfully, so I don't think that it's failing to return the success status.
I've done a lot of searching on this site and tried every suggestion I could find - adding a explicit "json" datatype parameter, switching from ":success" to ".done()" - but nothing has worked yet. I even tried switching from done() to always() - a bad idea but I wanted to see if it would get called...and it wasn't called.
It's also worth noting that the .fail() handler is also not being executed.
Is it possible that the JSON block we're sending back to indicate success is somehow failing to make jQuery realize that we were successful? Or is it possible that the AJAX call is crashing when it tries to process the successful return? If so, how do I catch that to prove it and fix it?
Hope someone can help.
First of all my knowledge of Backbone is very limited, and currently, I'm trying to add an implementation into some code I didn't create.
My problem is as follows:
I have a collection which is being rendered on click of a button. Now, we are setting some permissions on the website, so that sometimes the response I will get is a 401.
I'm currently able to get the response, the problem is that I don't know how to attach it to the sync event so that if I get a 401 when I call the API, it shouldn't render anything.
I would think looking at the code would help clarify my problem:
this.addressBook = new (Backbone.Collection.extend({
url: url,
model: Backbone.Model.extend({
idAttribute: 'ID'
}),
parse: function(data) {
return data;
}
}))();
this.addressBook.on('sync', this.renderAddresses, this);
this.addressBook.fetch();
So I found a few ways to get the status code from fetch, but in this particular case, I need to get the status code before the sync event calls this.renderAddress, and given the status of the response, go ahead and render my view or simply display a message stating that access is denied.
Sorry if I'm not clear enough.
Thanks in advance.
Here is the salient part of the backbone documentation:
Whenever a model or collection begins a sync with the server, a "request" event is emitted. If the request completes successfully you'll get a "sync" event, and an "error" event if not.
This means that the sync event shouldn't fire if you get a 401, rather the error event should be triggered.
You can test this in your code by listening to all the different events (all available parameters included):
this.listenTo(yourCollection, 'request', function(collection, resp, options) {
console.log('Request: ', resp);
});
this.listenTo(yourCollection, 'error', function(collection, resp, options) {
console.log('Error: ', resp);
});
this.listenTo(yourCollection, 'sync', function(collection, resp, options) {
console.log('Sync: ', resp);
});
So you should be able to just listen to the error event to display your custom error message:
this.listenTo(yourCollection, 'error', function(collection, resp) {
if (resp.status === 401) {
console.warn('401: Unauthorized');
} else {
// do something else
}
});
First of all, you will need to define some callback options for you addressBook fetch. For what you are trying to accomplish, you need to provide the error callback.
this.addressBook.fetch({
error: function(xhr) {
if(xhr.status == 401) { // Put logic you want in the case of 401 here...
}
});
Disclaimer: I have not tested this code, as I do not have a convenient way I can think of to reproduce this problem.
I believe it works because Backbone passes a jQuery xhr Object to its error callback. http://backbonejs.org/#Model-fetch
I'm trying to operate two servers.
MVC Web API service.
MVC Web application.
The idea is that the web application renders a page filled with javascript requests, which populate the actual data from the remote API service. The web application will never itself touch the database, or the API service (besides setting up authorisation tokens initially).
What is the best way to achieve this?
So far I've been using JQuery AJAX requests, attempting to use JSONP. However I always get "x was not called" exceptions.
$.ajax({
url: '#(ViewBag.API)api/customer',
type: 'get',
dataType: 'jsonp',
jsonp: false,
jsonpCallback: function (data) {
debugger;
// code to load to ko
},
error: function (xhr, status, error) {
alert(error.message);
}
});
Also the jsonpCallback function is called before the request is sent, so I assume its actually trying to call a function to generate a string? If I reform this request:
window.success = function (data) {
debugger;
// code to load to ko
};
... with jsonpCallback being "success", I still get the same error (but the success method is never called.
Any ideas? Thanks.
Edit: I've gotten started on the right course from this:
http://www.codeproject.com/Tips/631685/JSONP-in-ASP-NET-Web-API-Quick-Get-Started
Added the formatter, and replaced jsonCallback with success, like a normal ajax. However this only seems to work for get. I cannot delete or update. :(
Can you get it to work using the $.getJSON method?
$.getJSON( "ajax/test.json", function( data ) {
//handle response
});
Have you fired up developer tools in IE and watched the network traffic to see precisely what is being sent and returned?
I have a server function that generates JSON representing part of the file system.
The server function is called once the user has selected an item from a pull-down list.
So far so good.
My question is how do I display the tree ONLY when the JSON data has been returned from the server? Please make your answer as verbose and complete as possible as I'm not a javascript pro by any means!
var serverFunctionComplete = false;
var x = serverFunction();
while(!serverFunctionComplete) {
//just waiting
}
setTimeout(function() {
serverFunctionComplete = true;//if the server doesn't respond
}, 5000);
This should get you started.
You could make ajax request synchronous using the sync : true property in the xhr object. This stops other code from executing until the response is recieved from the server and the callback is done executing.
require(["dojo/request/xhr"], function(xhr){
xhr("example.json", {
handleAs: "json",
sync: true
}).then(function(data){
// Do something with the handled data
}, function(err){
// Handle the error condition
}, function(evt){
// Handle a progress event from the request if the
// browser supports XHR2
});
});
However, this is typically not the best practice as asynchronous loading as one of the great things about javascript and ajax. It would be reccomended to do display your tree in the callback function in the xhr so your script does not get hung up polling for a response.
require(["dojo/request/xhr"], function(xhr){
xhr("example.json", {
handleAs: "json"
}).then(function(data){
// Display your Tree!
}, function(err){
// Handle the error condition
});
});
For general asynchronous thread management, refer to Dojo's Deffered class.
I have the following JS/JQuery snippet:
function add_item() {
var item = $("input:text[name='new_item']").val();
$.post("{{ url_for('add_item') }}",
{'item' : item},
function(data) {
alert(':}');
});
}
It performs a simple AJAX request to a Flask webserver and displays an alert box on success (the data always returns a JSON snippet). The AJAX request adds a field to a SQLite database and returns. On my dev box, this request completes very quickly using asynchronous requests. However, on another server this request takes a few seconds (less than the default timeout, though) using asynchronous requests.
Problem: When the request takes a long time to complete using asynchronous requests, the callback is never called. When I change the AJAX settings to be synchronous, the callback is always called.
Thank!
I would try the $.ajax() function over the post one. Seems to have been more maintained - 1.6.2 also seems to have some issues, so try 1.6.1 if you need to: http://api.jquery.com/jQuery.ajax/
Use the error method to find out what error you're getting.
function add_item() {
var item = $("input:text[name='new_item']").val();
$.post("{{ url_for('add_item') }}",
{'item' : item},
function(data) {
alert(':}');
}).error(function(jqXHR, textStatus, errorThrown) { alert("error"); });
}