I have this website that connects with a local service that manages a CardReader with a PIN Pad. There are many different operations that can be completed using this device. Heres an example of one of them:
Before I used to chain the callbacks between each other, but now, because there are new operations, that also use methods like "lock" and "release", I need to change my code, so that the code for step 1 and 3 is reusable.
I have been trying to solve this with jQuery promises, but Im quite new to this, and I still havent really figured out how they work. Can someone give me a hand?
This is an example of the code im using now. I have removed the business logic from inside the functions, to simplify the example:
var CardReader = {
////////////////////
// Different possible messages to the Card Reader
////////////////////
lockDevice: function() {
this.makeAjaxCall("GET", "/LockDevice", this.lockDeviceCallback);
},
getPin: function() {
this.makeAjaxCall("POST", "/getPin", this.getPinCallback);
},
releaseDevice: function() {
this.makeAjaxCall("POST", "/Release", this.releaseDeviceCallback);
},
//////////////////
// Callbacks for each message to the Card Reader
//////////////////
lockDeviceCallback: function(jqXHR, textStatus) {
if (textStatus !== "success") { return; }
this.getCardLogin();
},
getCardLoginCallback: function(jqXHR, textStatus) {
if (textStatus !== "success") { return; }
this.releaseDevice();
},
releaseDeviceCallback: function(jqXHR, textStatus) {
if (textStatus !== "success") { return; }
//End
},
////////////////
// Other methods
////////////////
init: function() {
// UI BIndings
$(#button).on("click", this.logIn.bind(this));
},
logIn: function() {
this.lockDevice();
},
makeAjaxCall: function(callType, resource, callbackMethod) {
$.ajax({
type : callType,
url : "http://localhost:1337" + resource,
cache : false,
dataType : "json",
contentType: "application/json",
context : this,
complete : callbackMethod
});
}
};
This could fit your needs even i'm not sure to understand fully your problematic here.
The important point here seems to keep order on ajax method callbacks. You could do something like that:
Create these methods:
_nextCall: function (deferreds, method) {
if (deferreds.length) this._when(deferreds, method);
else console.log(method + " SUCCESS");
},
_when: function (calls, method) {
var $promise = $.when(this[calls[0]]())
$promise.then(function () {
calls.splice(0, 1);
this._nextCall(calls, method);
}, function () {
console.log(method + " FAILED on: " + calls[0]);
});
},
Use it like that e.g:
logIn: function logIn() {
var calls = ["lockDevice", "getCardLogin", "releaseDevice"];
this._when(calls, arguments.callee.name);
},
getPinOnly: function getPinOnly() {
var calls = ["getPin"];
this._when(calls, arguments.callee.name);
},
DEMO
COMPLETE CODE:
var CardReader = {
////////////////////
// Different possible messages to the Card Reader
////////////////////
lockDevice: function () {
return this.makeAjaxCall("GET", "/LockDevice", this.lockDeviceCallback);
},
getCardLogin: function () {
return this.makeAjaxCall("POST", "/getCardLogin", this.getCardLoginCallback);
},
getPin: function () {
return this.makeAjaxCall("POST", "/getPin", this.getPinCallback);
},
releaseDevice: function () {
return this.makeAjaxCall("POST", "/Release", this.releaseDeviceCallback);
},
//////////////////
// Callbacks for each message to the Card Reader
//////////////////
lockDeviceCallback: function (jqXHR, textStatus) {
console.log("lockDeviceCallback");
if (textStatus !== "success") {
return;
}
},
getCardLoginCallback: function (jqXHR, textStatus) {
console.log("getCardLoginCallback");
if (textStatus !== "success") {
return;
}
},
getPinCallback: function (jqXHR, textStatus) {
console.log("getPinCallback");
if (textStatus !== "success") {
return;
}
},
releaseDeviceCallback: function (jqXHR, textStatus) {
console.log("releaseDeviceCallback");
if (textStatus !== "success") {
return;
}
//End
},
////////////////
// Other methods
////////////////
init: function () {
// UI BIndings
$('#btn_login').on("click", $.proxy(this.logIn, this));
$('#btn_getPinCallback').on("click", $.proxy(this.getPinOnly, this));
},
_nextCall: function (deferreds, method) {
if (deferreds.length) this._when(deferreds, method);
else console.log(method + " SUCCESS");
},
_when: function (calls, method) {
var $promise = $.when(this[calls[0]]())
$promise.then(function () {
calls.splice(0, 1);
this._nextCall(calls, method);
}, function () {
console.log(method + " FAILED on: " + calls[0]);
});
},
logIn: function logIn() {
var calls = ["lockDevice", "getCardLogin", "releaseDevice"];
this._when(calls, arguments.callee.name);
},
getPinOnly: function getPinOnly() {
var calls = ["getPin"];
this._when(calls, arguments.callee.name);
},
makeAjaxCall: function (callType, resource, callbackMethod) {
return $.ajax({
type: callType,
url: "/echo/json", // + resource,
cache: false,
dataType: "json",
contentType: "application/json",
context: this,
success: callbackMethod
});
}
};
CardReader.init();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With