3

I know this is a highly answered topic, but reading tons of posts I can't figure if my dilema has a solution as I want.

I want to write a simple function that returns the User Name passing the UserId. It will be used everywhere to multiple purposes.

function getUserName(userId) {
    //...some code to retrieve the Name from a REST webservice like $.ajax or $.getJSON or anything else that helps me achieve my need
    return name;
}

$('#txtUserName').val(getUserName(sessionStorage.userId));
//...
if (getUserName(sessionStorage.userId) == getUserName($('#inputUser').val())) {
    alert('Error: User typed with the same name as '+ sessionStorage.userID);
}

I know that can rewrite it all to put callback's or whatever, but I want to know if there's any implementation that makes possible to write this simple function that returns a value from a PHP webService.

I imagine a function like this:

function getUserName(userId) {
    var users ={
        'me': 'Seak Oink'
        , 'you': 'Who knows'
        , 'jd': 'John doe'
    };
    return users[userId];
}

...but instead of having the fixed users object, i retrieve it from my php webService that gets it from a DB.

Using a callback, makes impossible to handle values. For example (if I'd use callback and assuming calling getUserName(userId, callback) handles the function call):

$('#txtUserName').val('');
getUserName(sessionStorage.userId, function(userName) {
    $('#txtUserName').val(userName);
});
if ($('#txtUserName').val() == '') {
    alert('user '+ sessionStorage.userId +' doesn't exist');
}

Instead, you could answer me to put it into the callback, but if need to call again my function, I must nest it to a callback again and again... I think it's a bad programming practice:

$('#txtUserName').val('');
getUserName(sessionStorage.userId, function(userName) {
    $('#txtUserName').val(userName);
    getUserName($('#inputUser').val(), function (userName2) {
        if (userName2 == userName) {
            alert('Error: User typed with the same name as '+ sessionStorage.userID);
        }
        //....here I must continue the code flow instead of continuing to caller's flow.
        //...nesting, and more nesting... impossible to read code?¿¿?:
        userpermission(userId, function(bAllowed) {
           if (bAllowed) {
              saveRecord(userId, sKey, sSomeText, function () {
                 alert('record saved -or not-');
                 // ...and continue nesting
              });
           } else {
             alert('forbidden');
           }
        });
    });
});

... instead of this simple code flow logic:

var lOk = false;
$('#txtUserName').val('');
$('#txtUserName').val(getUserName(sessionStorage.userId);
if ($('#inputUser').val() == getUserName($('#inputUser').val())) {
   alert('Error: User typed with the same name as '+ sessionStorage.userID);
}
if (userpermission(userId)) {
   lOk = saveRecord(userId, sKey, sSomeText);
} else {
   alert('forbidden');
}
if (lOk) {
  alert('record saved');
}
// ...continue the validation process or whatever

I understand the simple example of retrieving a value with a callback, but don't using it in code logic.

I've been read How do I return the response from an asynchronous call? and much more like that and understood, but I can't uderstand how to use retrieved values from different sources and apply the necessary logic. Basicly, how to order the chaos?

Community
  • 1
  • 1
Seak
  • 110
  • 8
  • 1
    Simplify your question, people don't like to parse bunch of words – Medet Tleukabiluly Jun 04 '16 at 11:04
  • I know it's complicated and confusing, but using callbacks like this is necessary when you're using asynchronous functions. You can use promises to simplify some of it, but it still has to use callbacks. – Barmar Jun 04 '16 at 11:12
  • You can't use the simple programming logic of sequential programs when you're getting the data from webservices. Sorry. – Barmar Jun 04 '16 at 11:13
  • The use of webservices are mandatory to retrieve database data. I can't understand why must nest the code into a callback from a callback from a callback... This programming form I think is unreadable and difficult to mantain unless you give me some structured rules to do it. As Regis says, I suffer callback hell. – Seak Jun 04 '16 at 11:28

1 Answers1

3

Looks like you're experiencing callback hell. That happens when you have several asynchronous functions and you need to handle all their errors and success.

That's exactly for that case that promises have been invented.

If you don't have ES6, have a look on jquery promises, otherwise they are built-in : ES6 promise

They allow more readable, synchronous like code.

For example, you can do code like that:

 $.when( // waits for two promises to be resolved
        getUserName(userId)
            .then(function(name) {  // once name resolved, fetch profile (new promise)
                return getUserProfile(name); 
            }),
        getUserPoints(userId) // another independent promise
   ).done(function(userProfile, userPoints) { // the two above are done, I can move on and update the DOM
       $("#profile").doSomething(userProfile); 
       $("#points").doOtherThing(userPoints);
   });
Community
  • 1
  • 1
Regis Portalez
  • 4,675
  • 1
  • 29
  • 41
  • It's a good point. I'll check if this programming philosophy matches with my ugly and limited brain – Seak Jun 04 '16 at 11:23
  • One question, @Regis-portalez: Outside the `$.when(` have I access to the results inside the `).done(` ? I mean if i read `$("#profile")` outside the `$.when` what I'll get? – Seak Jun 04 '16 at 11:30
  • depends on when you read it. if it's before the promise is resolved, you'll get nothing. That's why it's often convenient to work with observables (like in knockout or angular), but that's another subject... – Regis Portalez Jun 04 '16 at 11:55