0

I'm trying to perform, with ldapjs, a search for which the filter depends on the result of a first search

ldapClient.search(base1, opts1, (err1, res1) => {
    res1.on("searchEntry", entry => {
        const myObj = { attr1: entry.object.attr1 }
        const opts2 = { filter: entry.object.filter }

        if (entry.object.condition == myCondition) {
            ldapClient.search(base2, opts2, (err2, res2) => {
                res2.on("searchEntry", entry => {
                    myObj.attr2 = entry.object.attr2
                });
            });
        }

        console.log(myObj);
    });
});

The problem is that when console.log displays my object in the end, the event ".on" of my second search has not been traited yet.

So, how to tell my code to wait for the second event to finish, before display the object ?

Thanks

2 Answers2

0

You cannot see result of event when You do console.log(myObj)

Because of async behavior You've to wait for second search finish.

You've to put it inside of ".on":

ldapClient.search(base1, opts1, (err1, res1) => {
    res1.on("searchEntry", entry => {
        let myObj = { attr1: entry.object.attr1 }
        let opts2 = { filter: entry.object.filter }

        if (entry.object.condition == myCondition) {
            ldapClient.search(base2, opts2, (err2, res2) => {
                res2.on("searchEntry", entry => {
                    myObj.attr2 = entry.object.attr2
                    console.log("res2", myObj);
                });
            });
            return;
        }

        console.log("res1", myObj);
    });
});

also for elegant code You can use it like:

const async = require('async');

function ldapSearch(base, opts, callback) {
  ldapClient.search(base, opts, (err, res) => {
    if(err) return callback(err);

    res.on("searchEntry", entry => {
      callback(null, entry);
    });
  });
}

async.waterfall([
  function(done) {
    ldapSearch(base1, opts1, done);
  },
  function(entry, done) {
    if (entry.object.condition != myCondition) {
      return done("Condition not met");
    }

    let myObj = { attr1: entry.object.attr1 };
    let opts2 = { filter: entry.object.filter };
    ldapSearch(base2, opts2, (err, entry) => {
      myObj.attr2 = entry.object.attr2;
      done(null, myObj);
    });
  }
],
function(err, myObj) {
  if(err) {
    console.error(err);
    return;
  }

  console.log('MyObj', myObj);
});
num8er
  • 18,604
  • 3
  • 43
  • 57
0

Thank you num8er.

I finally used the "promised-ldap" module, based on ldapjs and promises

ldapClient.bind(dn, password).then(() => {

    let p;

    ldapClient.search(base1, opts1).then(res1 => {
        const entry = res1.entries[0].object;
        const myObj = { attr1: entry.attr1 };

        if (entry.condition == myCondition) {
            const opts2 = { filter: entry.filter }
            p = ldapClient.search(base2, opts2).then(res2 => {
                const entry2 = res2.entries[0].object;
                myObj.attr2 = entry2.attr2;
                return myObj;
            });
        } else {
            p = Promise.resolve(myObj);
        }

        p.then(value => console.log("Obj", value);
    });
});