Backbone.js error callback parameters getting replaced with model - backbone.js

I have a RESTful JSON api that I use to perform server-side calls like this:
Servlet.prototype.ajaxJSON = function (jobject, func, context) {
var self = this;
$.getJSON(this.name, jobject, function (json) {
...
}).fail(function(jqXHR, status, errorThrown) {
var callname = JSON.stringify(jobject).slice(1,JSON.stringify(jobject).indexOf(':'));
if(func !== null) {
func(JSON.parse('{' + callname+': {"error": "Server Error:' + errorThrown + '"}}'));
}
});
};
However, when I try to use the error callback in my model:
newComment.save(null, {
'success': _.bind(function(model, response) {
...
}, this),
'error': function(model, error) {
errorAlert(error, 'Could not post comment');
}
});
For some reason, I'm getting a Backbone model for my error parameter. I've stepped through the code and it looks like Backbone has some sort of custom wraperror method that's screwing everything up. Can anyone tell me what is going on here? Thanks!

Figured it out. The problem was with my model.sync method. I had a condition in it to check for an error that looked like:
if(_.isObject(json.post_comment) && json.post_comment.error) {
options.error(model, json.post_comment.error, options);
}
That needed to be:
if(_.isObject(json.post_comment) && json.post_comment.error) {
options.error(json.post_comment.error);
}
Guess I was reading the documentation wrong. :/

Related

How does Meteor methods return results?

I am using meteor/react for learning facebook graph api.
I want to access users' post on facebook timeline and display them on screen. How can that be done?
With the guidance of the solution provided here [How to perform common FB actions using Meteor?. I have tried the following code: server.js
Meteor.methods({
'seePost' : function(){
var graph=Npm.require('fbgraph');
if(Meteor.user().services.facebook.accessToken){
graph.setAccessToken(Meteor.user().services.facebook.accessToken);
var future = new Future();
var onComplete = future.resolver();
graph.get('/me/feed',function(err,result) {
console.log(result);
return onComplete(err,result);
})
Future.wait(future);
}
else{
return false;
}
}
});
client side code :
Meteor.call("seePost", function(err,result) {
if(err) console.log("error" , err);
else console.log("RES", result);
});
I expect the result displayed in the client side console since I want to show the users the posts on his/er timeline, But I get following output :
RES, undefined
You can do it using await and Meteor.callAsync
Basically the client code waits for the call to complete, and gives you the returned data
const result = await Meteor.callAsync("seePost");
Errors should be handled with a try..catch block
If you use fibers/future, you need to return something with "future".
const future = new Future();
// some code getting result or something
future.return(something);
return future.wait();
this will return something in the callback from client call.
try this code, when you're using fibers you need to "wait" for the response
Meteor.methods({
'seePost': function () {
var graph = Npm.require('fbgraph');
if (Meteor.user().services.facebook.accessToken) {
graph.setAccessToken(Meteor.user().services.facebook.accessToken);
var future = new Future();
var onComplete = future.resolver();
graph.get('/me/feed', function (err, result) {
console.log(result);
if (err) {
return future.return(false);
} else {
return future.return(result);
}
})
return future.wait();
}
return false;
}
});

TypeError: Cannot read property 'TEXT_TYPE' of undefined (BarcodeScanner)

I am using Ionic with BarcodeScanner that can be found here.
This is my code to encode a piece of text:
$scope.GenerateBarcode = function () {
$cordovaBarcodeScanner.encode($cordovaBarcodeScanner.Encode.TEXT_TYPE, "1", function(result){
console.log("result:" + result);},
function(fail){
console.log("encoding failed: " + fail);}
) };
However, I am getting the error in the question. This is weird since the plugin code that I use is:
function BarcodeScanner() {
/**
* Encoding constants.
*
* #type Object
*/
this.Encode = {
TEXT_TYPE: "TEXT_TYPE",
EMAIL_TYPE: "EMAIL_TYPE",
PHONE_TYPE: "PHONE_TYPE",
SMS_TYPE: "SMS_TYPE"
.......
I am accessing the object correctly as in the website (example in Cordova). Where is this error comming from?
Please note this part of documentation
$cordovaBarcodeScanner
.encode(BarcodeScanner.Encode.TEXT_TYPE, "http://www.nytimes.com")
.then(function(success) {
// Success!
}, function(error) {
// An error occurred
});
I assume that you can't access the types with $cordovaBarcodeScanner. You need to write cordova.plugins.barcodeScanner.Encode.TEXT_TYPE or maybe it works if you just write BarcodeScanner.Encode.TEXT_TYPE.
$cordovaBarcodeScanner
.encode("TEXT_TYPE", "Your text here")
.then(function (success) {
console.log(success);
// Success!
}, function (error) {
console.log(error);
// An error occurred
});

mapping the response to corresponding request

I am making $http request to multiple environment and processing after I get all the responses. I am using the code below:
$q.all(Object.keys($rootScope.envs).map(request)).then(function(res){
var results = {};
for (var env in res) {
results[env] = res[env].data;
}
}, function(err){
console.error(err);
});
function request(env) {
return $http.get(callService.getDomainUrl()+'/'+$rootScope.envs[env]+ '/hosts.json');
}
The above code works fine, but the results object looks like below:
{
0: {data:{}},
1: {data:{}},
2: {data:{}},
3: {data:{}}
}
I want the corresponding response for each key and the results should be like
{
env1: {data:{//data for env1}},
env2: {data:{//data for env2}},
env3: {data:{//data for env3}},
env4: {data:{//data for env4}},
}
How to map the corresponding response to the key? Please let me know how to get this as this is asynchronous request. Should I have something from the API to know which env the API is coming from?
I think the simplest way would be to push the result handling into the request function, that way you still have the 'env' value in scope.
var results = {};
$q.all(Object.keys($rootScope.envs).map(request)).then(function(res){
// Do something with 'results' here.
}, function(err){
console.error(err);
});
function request(env) {
return $http.get(callService.getDomainUrl()+'/'+$rootScope.envs[env]+ '/hosts.json')
.then(function(res) { results[env] = res.data; return env; });
}
Another option would be to replace my return env with return [env, res.data] and then you can go back to creating the results object as in your original code.
The important thing here is to remember you can handle the $http.get promises individually as well as using the promises from the call to then in $q.all.

Response status check using angularjs

I am trying to check response status by using following code:
$scope.coach = Coach.get(function(response) {
if(response.status === 401) {
alert("Coach");
}
});
but its not working, can anyone help please. thanks
$resource.get() takes two callbacks; the second is the error handler and receives the response object:
$scope.coach = Coach.get(
function (coach) {
// ... could do something with returned data object here
},
function (res) {
alert("Coach status: " + res.status);
}
);
Check this plunker for a working example: http://plnkr.co/edit/WHL63r?p=preview

How to send ajax response to Jquery from CakePhp?

I have this script in a view:
<script type="text/javascript">
$(document).ready(function() {
$("#addbrand").click(function() {
$.ajax({
url : '../brands/add',
data : {
name : "test",
shortname : "tst"
},
dataType : 'json',
success : function(html, textStatus) {
alert('Success ' + textStatus + html);
},
error : function(xhr, textStatus, errorThrown) {
alert('An error occurred! ' + errorThrown);
}
});
});
});</script>
And in add controller I have these lines:
... else if($this->request->is('ajax')){
if ($this->Brand->save($this->request->query)) {
// How to send feedback!?
}else{
// How to send feedback!?
}
$this->autoRender = false;
exit();
}
When I click addbrand, Ajax operation runs successfully and a I can see the added row in database, but I don't know how to send an error or success message to the user. I've read several tutorials but none of them were about cakephp2.0 while Everything is changed in 2.x.
I've also read JSON and XML views but unfortunately I didn't understand anything!!!
I need to send a status code. If the status was OK then I ought to to send an array of Strings (brand names actually) and if status is not OK I should send a string that explains why the operation is not completed successfully.
I'd be most grateful if anybody can help me. Thanks
Update:
I changed the code. I used CakeResponse() and now my action is like this:
if($this->RequestHandler->isAjax()){
if ($this->Brand->save($this->request->query)) {
return new CakeResponse(array('body'=> json_encode(array('val'=>'test ok')),'status'=>200));
}else{
return new CakeResponse(array('body'=> json_encode(array('val'=>'test not ok')),'status'=>500));
}
}
Using CakeResponse I can handle the possible responses in Jquery well.
$("#addbrand").click(function() {
$.ajax({
url : '../brands/add',
data : {
name : "test",
shortname : "tst"
},
dataType : 'json',
success : function(data) {
alert("The brand has been saved");
},
error : function(data) {
alert("Eorror occured");
},
complete : function(data) {
alert($.parseJSON(data.responseText).val);
}
});
});
Although it seems to me that everything is working now and I can send several variables through the Ajax between client and server in JSON format, I need to know if it's a standard way of sending Ajax responses in CakePHP or not? Is there any other simpler way for doing this?
The following lines of code do exactly whatever return new CakeResponse(array('body'=> json_encode(array('val'=>'test ok')),'status'=>200)); does in my question:
$this->set('val','test ok');
$this->set('_serialize',array('val'));
$this->response->statusCode(200);
Remember that you need to do two important things:
Add Router::parseExtensions('json'); to App/Config/routs.php.
Add var $components = array("RequestHandler"); to your controller.
I think this way is better because you don't need to return anything. In previous solution we had to return cakeresponse object and this, sits uneasy with the nature of actions.
You should use the JSON views with route extensions:
Firstly you need to set up route extensions. This is generally done with:
Router::parseExtensions('json'); // In App/Config/routes.php
This will enable Router to handle the 'json' extension and to know how to handle a request like:
www.example.com/people/index.json
if($this->RequestHandler->isAjax()){
if ($this->Brand->save($this->request->query)) {
//Logic for success
} else {
//Logic for save failure
}
}
At this point you have the ability to choose between using the data views with the serialize key or using a data view with view files (copyed from the CakeBook):
<?php
// Controller code
class PostsController extends AppController {
public function index() {
$this->set(compact('posts', 'comments'));
}
}
// View code - app/View/Posts/json/index.ctp
foreach ($posts as &$post) {
unset($post['Post']['generated_html']);
}
echo json_encode(compact('posts', 'comments'));
Notice that the view is located under .../Views/Posts/json/...
You can have multiple extensions in the router so you can return and handle all kinds of contents - after all it is all just data representation.
Cheers!

Resources