Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
158
rated 0 times [  159] [ 1]  / answers: 1 / hits: 33601  / 8 Years ago, fri, june 10, 2016, 12:00:00

I have the following function to check a users session to see if they're staff or not. Now, I know there are better ways to do this, but I'm trying to make a simple application that's tied with a forum software.



function isStaff(callback) {
$.ajax({
url: url
}).done(function(data) {
var session = $.parseJSON(data);
if (session.is_staff === 1) {
callback(true);
} else {
callback(false);
}

});
}


Let's say I'm using this function in, like so, when compiling a post (Handlebars).



function compilePost(post) {
var source = $('#feed-item-template').html();
var template = Handlebars.compile(source);
var context = {
id: post.id,
content: post.text,
author: post.author,
date: $.timeago(post.date),
staff: function() {
isStaff(function(response) {
return response;
});
}
}
var html= template(context);
return html;
}


Problem here, is that the request to check if a user is staff doesn't complete the request until after the function is ran.



I know with Promises is an alternative to async: false, where request is made and the response comes back before the function finishes.



But I have no idea how I can convert this into a promise. I've tried to learn it but I'm stuck at the concept. Can someone explain this to me? Thanks.


More From » jquery

 Answers
143

First, let's simplify the compilePost function. This function should know how to compile a post in a synchronous manner. Let's change the isStaff fetching to a simple argument.



function compilePost(post, isStaff) {
var source = $('#feed-item-template').html();
var template = Handlebars.compile(source);
var context = {
id: post.id,
content: post.text,
author: post.author,
date: $.timeago(post.date),
staff: isStaff
}

var html= template(context);
return html;
}


Now, let's create a new method, with a single purpose - checking if a user is member of the staff:



function checkForStaffMemebership() {
return new Promise(function (resolve, reject) {
$.ajax({
url: url,
success: function (data) {
var session = $.parseJSON(data);
if (session.is_staff === 1) {
resolve(true);
} else {
resolve(false);
}
}
});
});
}


This function wraps your original ajax call to the server with a promise, whenever the $.ajax call gets a response from the server, the promise will resolve with the answer whether the user is a staff member or not.



Now, we can write another function to orchestrate the process:



function compilePostAsync(post) {
return checkForStaffMemebership()
.then(function (isStaff) {
return compilePost(post, isStaff);
});
}


compilePostAsync finds out whether the user is a staff member or not. Then, it's compiling the post.



Please notice that compilePostAsync returns a promise, and thus if you used to have something like:



element.innerHTML = compilePost(post);


Now, you should change it to something like:



compilePostAsync(post).then(function (compiledPost) {
element.innerHTML = compiledPost;
});


Some notes:




  1. This is only an example, it surely misses some things (proper error handling for example)

  2. The isStaff and checkForStaffMemebership (original and new) do not get any argument, I guess you'd figure out how to pass the userId or any other data you might need

  3. Read about promises, it's a useful tool to have, there is a lot of data about it on the web, for example: MDN.


[#61824] Wednesday, June 8, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
devlin

Total Points: 474
Total Questions: 113
Total Answers: 100

Location: Sweden
Member since Fri, Apr 16, 2021
3 Years ago
devlin questions
Tue, Apr 27, 21, 00:00, 3 Years ago
Sat, Oct 31, 20, 00:00, 4 Years ago
Fri, Aug 28, 20, 00:00, 4 Years ago
;