How can I check if multiple properties exists on an object without being too verbose?

You can keep a reference to settings, which improves things a fair bit:

const verifyJanrainAppSettings = (options) => {
    const settings = options.JanrainAppSettings && options.JanrainAppSettings.settings;
    return settings &&
      settings.tokenUrl &&
      settings.capture && // ** This was missing in the question, but I think you need it
      settings.capture.clientId &&
      settings.capture.appId &&
      settings.capture.appDomain &&
      settings.capture.captureServer &&
      settings.httpLoadUrl &&
      settings.httpsLoadUrl;
};

While you could put some of those names in an array and use a loop, I think I'd leave it at that.

With optional chaining (new in ES2020), that first line could be:

    const settings = options.JanrainAppSettings?.settings;

The array version would look something like:

const settingsProps = "capture tokenUrl httpLoadUrl httpsLoadUrl".split(" ");
const captureProps = "clientId appId appDomain captureServer".split(" ");
const verifyJanrainAppSettings = (options) => {
    const settings = options.JanrainAppSettings && options.JanrainAppSettings.settings;
    return settings &&
      settingsProps.every(prop => settings[prop]) &&
      captureProps.every(prop => settings.capture[prop]);
};

adiga asks a good question. If you want existence rather than truthiness (you have truthiness in your question), you'll want in (or for an own property check, hasOwnProperty). For instance:

const settingsProps = "capture tokenUrl httpLoadUrl httpsLoadUrl".split(" ");
const captureProps = "clientId appId appDomain captureServer".split(" ");
const verifyJanrainAppSettings = (options) => {
    const settings = options.JanrainAppSettings && options.JanrainAppSettings.settings;
    return settings &&
      settingsProps.every(prop => prop in settings) &&
      captureProps.every(prop => prop in settings.capture);
};

I would opt for an utility function:

function contains(object, ...keys) {
  return keys.every((key) => key in object)
}

const verifyJanrainAppSettings = (options) => {
  return (
    contains(options.JanrainAppSettings, 'settings') &&
    contains(
      options.JanrainAppSettings.settings,
      'tokenUrl',
      'httpLoadUrl',
      'httpsLoadUrl',
      'capture'
    ) &&
    contains(
      options.JanrainAppSettings.settings.capture,
      'clientId',
      'appId',
      'appDomain',
      'captureServer'
    )
  )
}


Perhaps something like if (['my', 'options'] in myObject) ...

This is the right idea. However, you need to loop over the array of strings and check if each of them is in myObject. You can do this loop with Array.every(). The only disadvantage is this only works at the deepest level. Since you have several levels of nesting here it will still get kind of ugly:

const verifyJanrainAppSettings = (options) => {
    return options.JanrainAppSettings
      && options.JanrainAppSettings.settings // dont' forget this check
      && ['tokenUrl', 'httpLoadUrl', 'httpsLoadUrl', 'capture'].every(key => // added options.JanrainAppSettings.settings.capture check
        key in options.JanrainAppSettings.settings
      )
      && ['clientId', 'appId', 'appDomain', 'captureServer'].every(key =>
        key in options.JanrainAppSettings.settings.capture
      );
}

Tags:

Javascript