I would like to concatenate a series of strings populated from an XHR response. So, I've chosen to do it like this:
$.post('/API',null,'json')
.done(function(response){
if (response.status === 'success') {
location = response.data.city + ', ' + response.data.state;
}
})
.fail(function(){
location = previousLocation;
})
.always(function(){
$("#location").text(location);
});
This feels clunky. Should I be more defensive in assuming a response from the API? Would this be more elegantly handled by some kind of templating function?
2 Answers 2
I would suggest using then whenever possible. done and fail are specific to jQuery while then is a "standard" pseudo-interface for promises.
And if my jQuery isn't mistaken, the success handler will fire for 2xx and 3xx responses, while the fail handler will fire on 4xx and 5xx responses. You should take advantage of those instead of returning and checking statuses manually. The only time I remember APIs require using 2xx for errors is for Flash, for some reason.
Assuming response always has a data field and you want everything in the data field to be concatenated, you can use Object.keys, array.map and array.join.
Your code should end up looking like this. Two-space indent is a personal preference, but I go with it because it looks more compact.
$.post('/API',null,'json').then(function(response){
location = Object.keys(response.data).map(function(key){
return response.data[key];
}).join(', ');
}, function(){
location = previousLocation;
}).always(function(){
$("#location").text(location);
});
-
1\$\begingroup\$ If you are not using the
failcallback, any errors in thethencallback won't be handled. Also quite changed how the data should be concatenated here.Object.keysdoes not guarantee order. \$\endgroup\$Quentin Roy– Quentin Roy2015年10月12日 13:03:37 +00:00Commented Oct 12, 2015 at 13:03
This at least checks for whether there was a response on the needed properties.
$.post('/API',null,'json')
.done(function(response){
if (response.status === 'success') {
var city = response.data.city,
state = response.data.state;
location = city ? city : '' + city && state ? ', ' : '' + state ? state : '';
}
})
.fail(function(){
location = previousLocation;
})
.always(function(){
$("#location").text(location);
});
-
1\$\begingroup\$ Umm... that was a quick selfie. \$\endgroup\$200_success– 200_success2015年10月11日 19:48:58 +00:00Commented Oct 11, 2015 at 19:48
-
\$\begingroup\$ @200_success I'm working it out as I go, but I don't know if that level of checking is necessary. So it may not be a good solution. \$\endgroup\$Chris– Chris2015年10月11日 19:53:32 +00:00Commented Oct 11, 2015 at 19:53