2

I get a JSON String as a result from an API that looks like this:

{
    "batchcomplete": "",
    "query": {
        "pages": {
            "682482": {
                "pageid": 682482,
                "ns": 0,
                "title": "Human",
                "thumbnail": {
                    "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Akha_cropped_hires.JPG/119px-Akha_cropped_hires.JPG",
                    "width": 119,
                    "height": 200
                },
                "extract": "Humans (Homo sapiens) are a species of highly intelligent primates. They are the only extant members of the subtribe Hominina and—together with chimpanzees, gorillas, and orangutans—are part of the family Hominidae (the great apes, or hominids). Humans are terrestrial animals, characterized by their erect posture and bipedal locomotion; high manual..."
            }
        }
    }
}

The goal
I never know what the pageid will be and I need to retrieve the extract and thumbnail. The extract should be a String and the thumbnail an Object.

Wouldn't be much of an issue if it weren't for the random pageid.

What I've tried

const thumbnail = jsonObj.query[0].thumbnail;
const extract = jsonObj.query[0].extract;

Expected result

thumbnail = {
              "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Akha_cropped_hires.JPG/119px-Akha_cropped_hires.JPG",
              "width": 119,
              "height": 200
            }

extract = "Humans (Homo sapiens) are a species of highly intelligent primates. They are the only extant members of the subtribe Hominina and—together with chimpanzees, gorillas, and orangutans—are part of the family Hominidae (the great apes, or hominids). Humans are terrestrial animals, characterized by their erect posture and bipedal locomotion; high manual...";

4 Answers 4

4

It's a bit of a hack, but if you know there will always only be one pageid (or if you'll always want the first one), you can use Object.values:

const page = Object.values(t.query.pages)[0];
console.log(page.thumbnail, page.extract);
Sign up to request clarification or add additional context in comments.

1 Comment

Nice, wouldn't even call it a hack. Just a simple solution that solves the problem beautifully. Thank you for sharing!
0

The Object.keys function returns an array with all the keys in the given object. Then you may use the array that is returned to use any key of the object to access some value.

So you can do something like this:

const partialObj = {
  '682482': 'Value'
};

const keys = Object.keys(partialObj);
console.log(keys);

// Then you can access the value with the "unknown" key:
console.log(partialObj[keys[0]]); //=> Value

In your specific case:

const jsonObj = {
    "batchcomplete": "",
    "query": {
        "pages": {
            "682482": {
                "pageid": 682482,
                "ns": 0,
                "title": "Human",
                "thumbnail": {
                    "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Akha_cropped_hires.JPG/119px-Akha_cropped_hires.JPG",
                    "width": 119,
                    "height": 200
                },
                "extract": "Humans (Homo sapiens) are a species of highly intelligent primates. They are the only extant members of the subtribe Hominina and—together with chimpanzees, gorillas, and orangutans—are part of the family Hominidae (the great apes, or hominids). Humans are terrestrial animals, characterized by their erect posture and bipedal locomotion; high manual..."
            }
        }
    }
};

const unknownKeys = Object.keys(jsonObj.query.pages);
const unknownKey = unknownKeys[0]; // We are only using one key.
const thumbnail = jsonObj.query.pages[unknownKey].thumbnail;

console.log(thumbnail);

Please note that some objects may have more than one key. In the previous example, only one key (the first one Object.keys returns) is being used. The Object.keys function also does not guarantee any specific order in the returned array of keys.

If you do not care about the key (only the value), you may use the Object.values function.

Comments

0

A combination of e.g. Object.values and an object destructuring assignment will do the job.

const sample = {
  "batchcomplete": "",
  "query": {
    "pages": {
      "682482": {
        "pageid": 682482,
        "ns": 0,
        "title": "Human",
        "thumbnail": {
          "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Akha_cropped_hires.JPG/119px-Akha_cropped_hires.JPG",
          "width": 119,
          "height": 200
        }
      }
    }
  }
}

const {
  pageid,
  thumbnail,
} = Object.values(sample.query.pages)[0];

console.log(pageid);
console.log(thumbnail);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Comments

0

Here is an iterative solution using object-scan

Advantage is that it's easier to maintain (e.g. target a different key if the response structure changes)

// const objectScan = require('object-scan');

const myData = { batchcomplete: '', query: { pages: { 682482: { pageid: 682482, ns: 0, title: 'Human', thumbnail: { source: '...url...', width: 119, height: 200 }, extract: '...text...' } } } };

const extract = (data) => objectScan(['query.pages.*.{thumbnail,extract}'], {
  filterFn: ({ property, value, context }) => {
    context[property] = value;
  }
})(data, {});

console.log(extract(myData));
/* => {
  extract: '...text...',
  thumbnail: { source: '...url...', width: 119, height: 200 }
} */
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

Disclaimer: I'm the author of object-scan

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.