I am using CORS so all the API happens in api.mywebsite.com but the website is served via website.com.
I am wondering if there's a way I can set the setting of either jQuery or Backbone to always make AJAX requests to my api.mywebsite.com ?
In otherwords, I want to do this in my backbone collections:
url: '/books'
and have it automatically infer api.mywebsite.com/v1/books
For the collection you can specify the full URL:
YourApp.Collections.Books = Backbone.Collection.extend({
model: YourApp.Models.Book,
url: 'http://api.mywebsite.com/v1/books/'
});
And for individual resources you can use a function to generate the url:
YourApp.Models.Book = Backbone.Model.extend({
url: function() {
return 'http://api.mywebsite.com/v1/books/' + this.get('id')
}
});
Backbone has the urlRoot method that sets the root of all requests.
From the Backbone site:
var Book = Backbone.Model.extend({urlRoot : '/books'});
var solaris = new Book({id: "1083-lem-solaris"});
alert(solaris.url());
alerts "/books/1083-lem-solaris"
Of-course you can change that relative path to something else: put a dot in front to send it to the site root, or your specific site root, or give it an absolute path.
Documentation
Of course in jQuery you can build the URL to whatever you like in an AJAX request. Including to an absolute url as long as it's not another domain:
$.ajax({
type: "GET",
url: "http://api.mywebsite.com + "anything_you_want_to_add"
}).done(function(response) {
console.log(response);
receiveResponseMethodSomewhereElse(response);
});
And a quick Backbone example of using the url parameter of the Model or the Collection:
The showing the scripts I used:
<title>Backbone Test</title>
<meta charset="UTF-8">
<script src="jquery.js"></script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
And then I specifically pointed this backbone example at my localhost. You'd want to point it to your domain. I included all of the console logs and available responses for your debugging pleasure. Both options here are building urls from the book id as that's normall what your creating, Reading, Updating or Deleting from the server. I put this script directly within the body of the page and watched the console logs. Note: Backbone is expecting a JSON response.
<script>
var Book = Backbone.Model.extend({urlRoot: 'http://localhost/url_test'});
var BookCollection = Backbone.Collection.extend({
model: Book,
url: 'http://localhost/url_test'
});
var myExcellentBook = new Book({id: "book"});
var MyBooks = new BookCollection();
// getting it directly from the model
solaris.fetch({
success: function(model, response, options) {
console.log("SUCCESS");
console.log(model);
console.log(response);
console.log(options);
},
error: function(model, response, options) {
console.log("ERROR");
console.log(model);
console.log(response);
console.log(options);
},
complete: function(xhr, textStatus) {
console.log(textStatus);
}
});
// or fetch directly from the collection and
// normally you'd loop through the response or
// when creating new models, you can let backbone
// intialize them through the response
MyBooks.fetch({
success: function(model, response, options) {
console.log("SUCCESS");
console.log(model);
console.log(response);
console.log(options);
},
error: function(model, response, options) {
console.log("ERROR");
console.log(model);
console.log(response);
console.log(options);
},
complete: function(xhr, textStatus) {
console.log(textStatus);
}
});
</script>
And the php script at url_test is simply returning a JSON object.
<?php
echo '[{"id": "MyNewBook"}]';
Related
I have a google ad project which requires me to get multiple "setTargeting('', '');" from an object array on json file (via url) --> {"country": "Netherlands", "city": "Amsterdam" }. So far everything works; however, suppose the network fails, or requested JSON parse failed, etc - I'd like to pass an empty array to make sure that the slot will still show ads with no targeting.
What would be a good practise for it?
Advertisements.cachedCategoriesByUrl = {};
Advertisements.getCategories = function(categoriesUrl) {
var cachedCategories = Advertisements.cachedCategoriesByUrl[categoriesUrl];
if(cachedCategories){
return cachedCategories;
} else {
var getCategories = $.ajax({
url: categoriesUrl,
data: { format: 'json' },
error: function(jqXHR, status, thrownError) {
=> I'd like to pass an empty array so the slot will show
ads with no targetting set.
However this doesn't seem to be working.
Do I need to do callback?
}
});
Advertisements.cachedCategoriesByUrl[categoriesUrl] = getCategories;
return getCategories;
}
}
Note:
return getCategories runs before the ajax call finishes. How do I make sure that return getCategories gets my error update(I want to pass an empty array if JSON request fails or invalid). Sorry I am in the learning process.
Solved it with this:
$.ajax({
url: ad.categoriesUrl
}).then(function(data){
Advertisements.advertisementSlot(ad, data);
}, function(data){
data = {};
Advertisements.advertisementSlot(ad, data);
});
I'm fairly new to asp.net MVC but am baffled as to why my request isn't working.
I'm trying to send an ajax request with jquery as per:
jQuery(function ($) {
var total = 0,
share = $('div.share'),
googlePlusUrl = "https://plusone.google.com/_/+1/fastbutton?url=http://bookboon.com" + $(location).attr('pathname');
setTimeout(function() {
$.ajax({
type: 'GET',
data: "smelly",
traditional: true,
url: share.data('proxy'),
success: function(junk) {
//var $junk = junk.match(regex);
console.log(junk);
},
error: function (xhr, errorText) {
console.log('Error ' + xhr.responseType);
},
});
}, 4000);
And set a line in my RouteConfig as:
routes.MapRoute(null, "services/{site}/proxy", new { controller = "Recommendations", action = "Proxy" });
The markup has a data-attribute value as:
<div class="share" data-proxy="#Url.Action("Proxy", "Recommendations")">
And my Proxy action method starts with:
public ActionResult Proxy(string junk)
The problem is that the junk parameter is always null. I can see in the debug output that the route seems to correctly redirect to this method when the page loads (as per jQuery's document ready function), but I cannot seem to send any data.
I tried sending simple data ("smelly") but I don't receive that neither.
Any suggestions appreciated!
The model binder will be looking for a parameter in the request called junk, however you're sending only a plain string. Try this:
$.ajax({
type: 'GET',
data: { junk: "smelly" }, // <- note the object here
traditional: true,
url: share.data('proxy'),
success: function(junk) {
//var $junk = junk.match(regex);
console.log(junk);
},
error: function (xhr, errorText) {
console.log('Error ' + xhr.responseType);
},
});
I have a RESTful json API, which I need to access in my front-end Backbone site.
So, I did this:
/* Goal collection */
var GoalCollection = Backbone.Collection.extend({
model: GoalModel,
url: "http://staging.api.hiwarren.com:8080/api/v1/goals/?callback=?",
sync: function(method, collection, options) {
options.dataType = "jsonp";
// options.timeout = 10000;
return Backbone.sync(method, collection, options);
},
parse: function(response) {
return response.results;
}
});
/* View for the goal collection */
var GoalCollectionView = Backbone.View.extend({
tagName: 'ul',
initialize: function(callback){
var that = this;
_.bindAll(this, 'render');
that.collection = new GoalCollection();
that.collection.bind('reset', this.render)
that.collection.fetch({
dataType: 'jsonp',
success: function(collection, response){
that.render();
if(callback) callback(that);
},
error: function(collection, response){
throw new Error("Goal fetch error - " + response.statusText);
}
});
},
render: function(){
this.collection.each(function(goal){
var goalView = new GoalView({ model: goal });
this.$el.append(goalView.render().el);
}, this);
return this;
}
});
I am trying to use JSONP, because it is a different domain. I've followed answers to questions similar to this, as you can see in my code, but it doesn't work.
Instead, I get this error message:
Uncaught Error: Goal fetch error - load
Backbone.View.extend.initialize.that.collection.fetch.error
options.errorjquery.js:3094 jQuery.Callbacks.fire
jQuery.Callbacks.self.fireWithjquery.js:8261 done
jQuery.ajaxTransport.send.jQuery.prop.on.callback
jQuery.event.dispatchjquery.js:4116 jQuery.event.add.elemData.handle
What am I doing wrong? How can I make this work?
Are you sure that the domain you are trying to access has support for jsonp? Some sites only enable the json format.
I am developing a backbone application which involves fetching data from an external API.
My application's domain is product.site1.com whereas domain of API is api.site1.com.
This is how my model and collection looks
var pModel = new Backbone.Model.extend({});
var pCollection = new Backbone.Collection.extend({
model: pModel,
url: 'api.site1.com/product'
});
and view looks like the below
var pView = new Backbone.View.extend({
initialize: function() {
var _this = this;
var pCollectionVar = new pCollection();
pCollectionVar.fetch({
dataType: 'jsonp',
beforeSend: _this.sendAuthentication,
success: function(collection, response, options) {
console.log(collection);
},
error: function(collection, xhr, options) {
console.log("error");
}
});
}
sendAuthentication: function(xhr) {
xhr.setRequestHeader('customKey1', 'ABCD');
xhr.setRequestHeader('customKey2', '1234');
}
});
When I execute this, my application makes a get request to the API server, whereas I am not getting the header data at the server end. I don't see these custom headers set for the request in my chrome dev tools either.
EDIT:
OPTIONS http://api.site1.com/product 405 (Method Not Allowed) jquery-1.10.2.js:8706
OPTIONS http://api.site1.com/product Invalid HTTP status code 405 jquery-1.10.2.js:8706
XMLHttpRequest cannot load http://api.site1.com/product. Invalid HTTP status code 405 (index):1
These are the errors I am getting while performing the request.
if you want to use sendAuthentication like you do it should be a global function:
pCollectionVar.fetch({
dataType: 'jsonp',
beforeSend: sendAuthentication,
success: function(collection, response, options) {
console.log(collection);
},
error: function(collection, xhr, options) {
console.log("error");
}
});
function sendAuthentication(xhr){
//Code goes here
}
Although this pollutes the global scope, I would use namespace:
var MyApplication = {};
MyApplication.sendAuthentication = function(xhr){ //code inside}.
pCollectionVar.fetch({
dataType: 'jsonp',
beforeSend: MyApplciation.sendAuthentication,
success: function(collection, resp){//rest...}
EDIT:
as described here, jsonp is not an ajax call and can't be treated as such
i want to get value from this API http://demo82.com/lois/api/get_page/?id=6 using Backbone js. i tried but i don't know how can we get values from object in backbone.
here is my Backbone code
Page = Backbone.Model.extend({
initialize: function() {
this.on('all', function() { console.log(this.get('page')); });
},
url: "http://demo82.com/lois/api/get_page/?id=6",
defaults: {
"id":null,
"title":"",
"content":""
}
});
var page = new Page();
console.log(page.fetch({}));
i am new and try to learn backbonejs please explain what is the better way ? please give me ans using jsfiddle.net.
thanks
Is id always going to be 6? In your code, your model is always getting the 6th thing. If you want a custom url with a get parameter, override url as a function:
url: function() {
id = this.get("id");
return "loispage/api/get_page/?id=" + id
}
Better yet, if you have control over the server side and can do something a little more RESTful with a page entity -- simply set urlRoot
urlRoot: "loispage/api/page/"
and fetch will automatically do an HTTP get from
"http://.../loispage/api/page/<id>
It looks like a context problem (this doesn't refer to the model in on's callback). You can fix this by specifying the context:
this.on('all',
function() { console.log(this.get('pagel')); },
this
);
Edit
There's also a cross-domain issue. You'll need to use a JSONP request for this by overriding sync and parse. (I adapted the following code from this example.)
var Page= Backbone.Model.extend({
// override backbone synch to force a jsonp call
sync: function(method, model, options) {
// Default JSON-request options.
var params = _.extend({
type: 'GET',
dataType: 'jsonp',
url: model.url(),
processData: false
}, options);
// Make the request.
return $.ajax(params);
},
parse: function(response) {
// parse can be invoked for fetch and save, in case of save it can be undefined so check before using
if (response) {
console.log(JSON.stringify(response));
// here you write code to parse the model data returned and return it as a js object
// of attributeName: attributeValue
return { status: response.status }; // just an example
}
},
Here's a JSFiddle demo.