0

I have to parse a json object that can be a string, array, array of strings and array of object. I realised that it's not good from the beginning that one object can be many types, but I can't change the code from upstream so I'll have to deal it in my code instead. I'm building a pixel library for modern browser so I'm not using jQuery or lodash. I'm supporting most modern browser and IE >= 9

Here's the example of the data that can be returned

"author": {
 "@type": "Person",
 "name": "Author"
}

Or

"author":[{"@type":"Person","name":"Author"}]

Or

"author": 'Author'

Or

"author": ['Author', 'Author1']

And this is my code.

  let obj = {};
  try {
    const json = document.querySelector('div.json');
    if (json) {
      let disc = JSON.parse(json.innerHTML);
      let authors = disc.author;

      if (typeof authors !== 'undefined' && Array.isArray(authors) && authors.length > 0) {
        authors = authors.map((author) => {
          if (typeof author === 'object' && author.name) {
            return author.name;
          } else {
            return author;
          }
        });
      }

      if (typeof authors !== 'undefined' && !Array.isArray(authors) && typeof authors === 'object') {
        authors = [authors.name];
      }

      if (typeof authors !== 'undefined' && typeof authors === 'string') {
        authors = authors.split(',');
      }

      obj.cAu: authors.join(',');
    }
  } catch (e) { }

  return obj;

My question is, is there a better way to do this in a more efficient way?

2
  • 3
    Probably better over at codereview.stackexchange.com Commented Jul 22, 2016 at 19:27
  • 1
    don't try everything, just the part that can explode... Commented Jul 22, 2016 at 19:28

2 Answers 2

1

How about:

switch (typeof authors) {
    case 'object':
        if ( Array.isArray(authors) ) {
            authors = authors.map((author) => {
                if (typeof author === 'object' && author.name) {
                    return author.name;
                } else {
                    return author;
                }
            });
        } else {
            authors = [authors.name];
        }
    break;   
    case 'string':
        authors = authors.split(',');
    break;
    case 'undefined':
        //
    break;
}
Sign up to request clarification or add additional context in comments.

Comments

1

Just for the record: here is a minimalist1, yet functional version.

switch((Array.isArray(authors) && 1) | (typeof authors[0] == 'string' && 2)) {
  case 0: return [authors.name];
  case 1: return [authors[0].name];
  case 2: return authors.split(',');
  case 3: return authors;
}

JSFiddle

1 needless to say, with a minimalist protection against unexpected inputs as well...

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.