I am using a Javascript library called ATS (Authenticated Traffic Solution). I am not sure if this is the right title for my issue but I am getting an unexpected value from a method returning either a promise or a concrete value if a callback is defined.
The method is the following:
ats.retrieveEnvelope(callback);
Fetch the envelope from configured storage; the callback function is optional. If the function is called without a callback, a promise will be returned. If the function is called with a callback, an envelope value will be returned.
Also from the docs I know that the returned envelope should be of the form:
{
   "envelope:"sdfasdfasdfa"
}
This is how I am using it in my code then
updateSomething(): Promise<void> {
    return new Promise<void>((resolve, reject) => {
       this.loadEnvelope()
          .then(updatedOrNewEnvelopeWrapper => {
            this.sendSync(updatedOrNewEnvelopeWrapper);
            resolve();
          })
          .catch(error => {
            console.error(`Error while retrieval ${error}`);
            reject(error);
          });
    });
  }
 private loadEnvelope(): Promise<string> {
    return retryPromise<string>(
      () =>
        new Promise<string>((resolve, reject) => {
          if (this.ATSOnPage()) {
            try {
              resolve(this.getFromATS());
            } catch (error) {
              console.error('Some error');
              reject(error);
            }
          } else {
            reject(new Error('Some other error'));
          }
        }),
      this.maxATSRetrievalRetries,
      this.retryDelay
    );
  }
  private getFromATS(): string {
    return this._window.ats.retrieveEnvelope(function (envelope: string) {
      return JSON.parse(envelope).envelope;
    });
  }
The value of updatedOrNewEnvelopeWrapper is always
{
   "envelope": "fasdfasdf"
}
while I would expect for the JSON to have been successfully parsed under getFromATS, so updatedOrNewEnvelopeWrapper would have been just the string fasdfasdf.
I changed the getFromATS like so:
  private getFromATS(): string {
    return this._window.ats.retrieveEnvelope(function (envelope: string) {
      console.log('Located ATS.js');
      var parsed = JSON.parse(envelope);
      while ('envelope' in parsed && typeof parsed.envelope == 'object') {
        parsed = parsed.envelope;
      }
      if ('envelope' in parsed && typeof parsed.envelope == 'string') {
        if (parsed.envelope.includes('envelope')) {
          console.log(`JSON string is ${parsed.envelope}`);
          const jsonString = JSON.parse(parsed.envelope);
          return jsonString.envelope;
        } else return parsed.envelope;
      } else throw new Error('Malformed ATS response');
    });
  }
}
so that it can check arbitrarily deep in the json struct to find the final envelope value, since I thought that maybe the return value would be
{
  "envelope": {
    "envelope":{
      "envelope":"asdfasdfasdf"
    }
  }
}
I also though that the envelope would be a json string itself like:`
{
   "envelope": '{"envelope":"asdfasdfa"}'
}
Nevertheless, I am still getting the value of updatedOrNewEnvelopeWrapper as {"envelope":"asdfasdfa"}
Can you spot the bug?
 
    