Wrapping Backbone sync requests - javascript

I am writing a Backbone application, and I need to offer some feedback to users whenever a request to the server is made (annoying, I know, but I have no control over this behaviour of the application). The backend always reports an informative (at least in theory) message with every response, like
{
"status":"error",
"message":"something went really wrong"
}
or
{
"status":"success",
"message":"congratulations",
"data":{...}
}
What I would like to understand is where to put a hook for some kind of messaging service.
One possibility is the parse() method for models and collections. To avoid duplication, I would have to put it inside some model base class. It is still a bit annoying since all models and collections have their own parse() anyway.
A more reasonable place to look would be the Backbone.sync function. But I do not want to overwrite it, instead I would like to wrap it inside some other helper function. The problem here is that I cannot find a good hook where to put some logic to be executed with every request.
Do you have any suggestions on how to organize some piece of logic to be executed with every request?

Since Backbone.sync returns whatever $.ajax returns, it is easy to achieve what I want by using jQuery delegates, like this
var originalMethod = Backbone.sync;
Backbone.sync = function(method, model, options) {
var request = originalMethod.call(Backbone, method, model, options);
request.done(function(msg) {
console.log(msg);
});
request.fail(function(jqXHR, textStatus) {
console.log(jqXHR, textStatus);
});
return request;
};

Assuming you are using a recent (>1.5) jquery all results from sync will return the $.ajax promise.
You can do it then without overriding anything in sync by using that promise. For example, if you did a fetch(), you could do:
var p = mymodel.fetch();
p.done(function (res) { ... });
p.fail(function (err) { ... });
Of course you can also use callbacks in fetch options, but I find the above much cleaner. The same pattern applies for say save or anything that uses sync.

Related

how to call a service in vanilla js in a asp.net model

I am trying to call a service in js in a asp.net model.
can you please help me find the right structure,
here is my general code.
GetSomething: function () {
var something;
System.SomeService.GetSomething(new Report.DocumentsRequest(), null, function (response) {
return something = Report.GetResponse(response);???
});
return something = Report.GetResponse(response);???
//
},
tank you for the help
It's hard to tell out of context, but it looks as though you're attempting to mix C# code with JavaScript code. If that's the case, you cannot do that. Instead, you need to provide an endpoint (controller action) that accesses your service and returns the results as something like JSON. Then, you need to utilize AJAX (the XMLHttpRequest object) in your JavaScript to make a request to that endpoint.

Deps autorun in Meteor JS

Decided to test out Meteor JS today to see if I would be interested in building my next project with it and decided to start out with the Deps library.
To get something up extremely quick to test this feature out, I am using the 500px API to simulate changes. After reading through the docs quickly, I thought I would have a working example of it on my local box.
The function seems to only autorun once which is not how it is suppose to be working based on my initial understanding of this feature in Meteor.
Any advice would be greatly appreciated. Thanks in advance.
if (Meteor.isClient) {
var Api500px = {
dep: new Deps.Dependency,
get: function () {
this.dep.depend();
return Session.get('photos');
},
set: function (res) {
Session.set('photos', res.data.photos);
this.dep.changed();
}
};
Deps.autorun(function () {
Api500px.get();
Meteor.call('fetchPhotos', function (err, res) {
if (!err) Api500px.set(res);
else console.log(err);
});
});
Template.photos.photos = function () {
return Api500px.get();
};
}
if (Meteor.isServer) {
Meteor.methods({
fetchPhotos: function () {
var url = 'https://api.500px.com/v1/photos';
return HTTP.call('GET', url, {
params: {
consumer_key: 'my_consumer_key_here',
feature: 'fresh_today',
image_size: 2,
rpp: 24
}
});
}
});
}
Welcome to Meteor! A couple of things to point out before the actual answer...
Session variables have reactivity built in, so you don't need to use the Deps package to add Deps.Dependency properties when you're using them. This isn't to suggest you shouldn't roll your own reactive objects like this, but if you do so then its get and set functions should return and update a normal javascript property of the object (like value, for example), rather than a Session variable, with the reactivity being provided by the depend and changed methods of the dep property. The alternative would be to just use the Session variables directly and not bother with the Api500px object at all.
It's not clear to me what you're trying to achieve reactively here - apologies if it should be. Are you intending to repeatedly run fetchPhotos in an infinite loop, such that every time a result is returned the function gets called again? If so, it's really not the best way to do things - it would be much better to subscribe to a server publication (using Meteor.subscribe and Meteor.publish), get this publication function to run the API call with whatever the required regularity, and then publish the results to the client. That would dramatically reduce client-server communication with the same net result.
Having said all that, why would it only be running once? The two possible explanations that spring to mind would be that an error is being returned (and thus Api500px.set is never called), or the fact that a Session.set call doesn't actually fire a dependency changed event if the new value is the same as the existing value. However, in the latter case I would still expect your function to run repeatedly as you have your own depend and changed structure surrounding the Session variable, which does not implement that self-limiting logic, so having Api500px.get in the autorun should mean that it reruns when Api500px.set returns even if the Session.set inside it isn't actually doing anything. If it's not the former diagnosis then I'd just log everything in sight and the answer should present itself.

Mocking Angular $resource

Could anybody suggest me a way how to mock $resource object
I've searched though internet, but all my tries were finished by KARMA testing.
I don't need it.
My idea is to have just fake object, so I will be able to switch between $resource implementations in my app.
Thanks.
You can use $provide to do this.
angular.module(“MyApp”,[])
.config([“$provide”,function($provide){
$provide.decorator(“$resource”,function($delegate, myReplacementResource){
//$delegate is the original $resource, if you just want to modify it
//either inject a replacement resource that you have already registered
//as a factory (recommended). Or make it here.
return myReplacementResource;
});
}])
dskh presented one way to do it. Here's a another way which you might find to be easier... although it's ofen used for unit testing, you can use angular-mocks.js in your app as well:
app.run(function($httpBackend) {
$httpBackend.whenPOST('/string/match/url').respond(function (method, url, data) {
return [{some:data}];
});
$httpBackend.whenGET(/regexpmatch/).respond(function (method, url, data) {
return {some:{other:data}};
});
// pass through other stuff
$httpBackend.whenPOST(/.*/).passThrough();
$httpBackend.whenGET(/.*/).passThrough();
$httpBackend.whenDELETE(/.*/).passThrough();
$httpBackend.whenJSONP(/.*/).passThrough();
$httpBackend.whenPUT(/.*/).passThrough();
});
This plunk shows how I go about mocking resource objects, from a angular service, in a controller. I use SinonJs to fake a resource object. Then I basically fake the promise chain by injecting $q.
To fake the promise chain you need to get a defer object from $q, then get a promise from it.
In your tests, you then either fake a success or a failure by calling promise.resolve() or promise.reject() on that promise. You can fake data from the server by passing an object in as a parameter like this promise.reject(someData).
You then have to make sure that you scope.apply(). To make sure that whatever it is you wanted to do becomes visible on scope.
I'm not entirely sure if this is the right way to go about this, but it has been working for me.

extjs commit answer from server to store

I try to develop my own proxy (extends Ext.data.proxy.Proxy). after getting the response from my server (json) I can decode it and using my Json reader I create the set of records to commit to the store. As I understand I have to create an Operation object and commit the data with operation.commitRecords(). But this line if (clientRecords && clientRecords.length) never passes as clientRecords is undefined. I cannot understand how to use this object neither how to initialize it. This is my current code:
options.action = options.action || 'read';
var operation = new Ext.data.Operation(options);
var json = reader.read(response);
operation.commitRecords(json.records);
What should I do in order to commit the records?
Thanks in advance!
That's not the proxy that is supposed to create the operation, it is the store. Then it passes this operation to the proxy, along with a callback. The proxy executes the operation in its own way and, when it is done, use the callback to notify the store.
So, the short answer to your question is that you need to execute the callback passed to the CRUD method you're implementing. Let's say it's read (Amit's right that some context about your code could have helped). So that would be something like:
// see, the operation is given to us
read: function(operation, callback, scope) {
var me = this;
doWebsocketMagic(function() {
// notify the store
Ext.callback(callback, scope || me, [operation]);
});
}
Now, that won't be enough, because proxies are expected to manipulate the operation. You'll have to read the code from other proxies to know how. ServerProxy would have saved you that work, but you're not working with HTTP requests ("ServerProxy should ideally be named HttpProxy"). No luck.
So you should start by read the code of the read method of MemoryProxy. It offers, in one single place, an example of everything (I think) that you've got to do.
Then, maybe you can go clever about it:
Ext.define('My.WebsocketProxy', {
extend: 'Ext.data.proxy.Memory'
,read: function(operation, callback, scope) {
var me = this;
doWebsocketMagic(function(response) {
me.data = response;
Ext.data.proxy.Memory.prototype.read.call(me, operation, callback, scope);
});
}
});
Ok...Having searched how the store initializes the operation then it calls the proxies read method with callback function onProxyLoad(operation);. So adding store.onProxyLoad(operation); populates the store properly. Thanks for the replies guys...they helped solving my problem.

Performance concerns about wrapping every method with "try catch" in JavaScript

I want to know your opinions on a function I made, that wraps every method of an object, adding "try catch" handlers to log JavaScript errors on server side.
I don't want to use window.onerror, because of this security restriction, and my scripts are going to be hosted on a different domain on a CDN.
/*
* object: Object to be wrapped
* errorHandler: Instance of ErrorHandler Object
*/
function addLog(object, errorHandler) {
var name, method;
for (name in object) {
method = object[name];
if (typeof method === "function") {
object[name] = function(method, name) {
return function() {
try {
return method.apply(this, arguments);
} catch (ex) {
ex.message += "; method: '" + name + "'";
errorHandler.addToStack(ex.message);
throw ex;
}
};
}(method, name);
}
}
return object;
}
errorHandler.addToStack is a method on a custom object that asynchronously sends error reports to a server using Ajax messages.
I want to wrap every object instantiated on my application with this function, but I'm not sure if:
Is this a bad practice?
Does it has performance issues?
Are there's a better ways for doing this?
Thanks in advance!
I think that the best way is to avoid try catch statements by preventing errors to occur adding validations and checks, but if you really need to do it this way, I don't think it will have a great performance issue.
Here I made a jspref test to measure it, and the difference shows only in IE, but it's not very significant.
I don't know if the errorHandler method has performance problems or slows down your code, but if it is async, I guess it won't be a problem.
Unlike stricter codes like Java, Javascript doesn't require try/catch for most objects instanciated. It tends to simply just not work if something goes wrong, and doesn't explode or end on you.
Some parts do however end the function, so a better method would be to surround the code as a whole with a try/catch, so that it fails silently, and use the catch to recall the original code while sending off an error report.
you can still send log to server using a global try/catch because exception objects contains the information.
however error object is not standard among browsers, i think

Categories

Resources