2

Iam using ldapjs library for my project with standard LDAP server and iam trying to using search(). Its working right until i want to return results.

So i believe its more my misunderstanding of how javascript works rather than library as its working fine console.log

Secondly iam not sure if iam using nested search() correctly and efficiently.

Any help would be appreciated

function getPhones() {

  return new Promise((resolve, reject) => {
  let phones = [];
  const opts = {
    filter: `(objectClass=Phone)`,
    scope: 'sub',
    // attributes: ['*'],
  };
     client.search(`cn=${callserver.cn},cn=Modules`, opts, function (err, res) {
        if (err) {
          console.log('Error in promise', err);
        }
        res.on('searchEntry',  function  (entry) {
          let newPhone = {};
          const opts2 = {
            filter: `(objectClass=*)`,
            scope: 'sub',
          };
           client.search(`${entry.object.dn}`, opts2, function (err, res) {
            res.on('searchEntry', function (entry2) {
              newPhone = entry2.object;
              console.log(newPhone); //here its logging just fine with all attributes
            });
          });
          console.log(newPhone);// here newPhone is empty
          phones.push(
            { ...entry.object, details: newPhone } 

            // followMeTo: entry.object.followMeTo,
            // telephoneNumber: parseInt(entry.object.telephoneNumber),
          );
        });
        res.on('end', function () {
          resolve(phones);
        });
        res.on('err', function () {
          reject('Error');
        });
      });
}
}

UPDATE 1: if i try to use as suggested:

    client.search(`${entry.object.dn}`, opts, function (err, res) {
            res.on('searchEntry', function (entry2) {
              phones.push({ ...entry.object, detail: entry2.object });
            });
          });

in here i cant access phones array, or nothing is pushed into it so i have to do it this way:

    client.search(`${entry.object.dn}`, opts, function (err, res) {
            res.on('searchEntry', function (entry2) {
            });
            phones.push({ ...entry.object, detail: entry2.object });
          });

but here i lose access to entry2 :-(

Losing my mind now

Jakub Koudela
  • 160
  • 1
  • 18
  • "*but here i lose access to entry2*" do you get a "`phones` is `undefined` error? if not it is defined there. The problem might be that we resolve the promise with phones before all of them are pushed. That I can't tell because I don't know how the API works, it looks to be like you're trying to put a promise wrapper around web sockets connection. I made an assumption that `res.on("end"` is only called when every `searchEntry` is done – T J Mar 13 '21 at 11:58
  • It looks like you need to make the first `client.search(`cn=` wait for the second one `client.search(`${entry` – T J Mar 13 '21 at 11:59

1 Answers1

0

I am not familiar with this API, but it looks like your code would be something like this:

function getPhones() {
  return new Promise((resolve, reject) => {
    let phones = [];
    const opts = {
      filter: `(objectClass=Phone)`,
      scope: "sub"
    };
    client.search(`cn=${callserver.cn},cn=Modules`, opts, function (err, res) {
      if (err) {
        console.log("Error in promise", err);
      }
      res.on("searchEntry", function (entry) {
        const opts = {
          filter: `(objectClass=*)`,
          scope: "sub"
        };
        client.search(`${entry.object.dn}`, opts, function (err, res) {
          res.on("searchEntry", function (entry2) {
            phones.push({
              ...entry.object,
              ...{
                details: entry2.object
              }
            });
          });
        });
        res.on("end", function () {
          resolve(phones);
        });
        res.on("err", function () {
          reject("Error");
        });
      });
    });
  });
}

The problem with below code:

client.search(`${entry.object.dn}`, opts2, function (err, res) {
    res.on('searchEntry', function (entry2) {
        newPhone = entry2.object;
        console.log(newPhone); //here its logging just fine with all attributes
    });
});
console.log(newPhone);// here newPhone is empty

Is that JS executes client.search() which is an async action, and without waiting for the response continues to execute the console.log(newPhone);.

So the fix here would be to simply push phones into results when the response comes back, within the success callback.


Side note:You can also look into async await if you want to write the code that "looks" synchronous

T J
  • 42,762
  • 13
  • 83
  • 138