Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cheerio Map Strange Behaviour

I'm using map with a list of Cheerio results to return an attribute value. What I want is a variable that contains a list of attribute values (in this case ID's), but instead I'm getting the ID's and extra data.

The following code prints a list of ID's:

let ids = $('[data-profileid]').map(function() {
    console.log($(this).attr('data-profileid'))
})

Result:

1012938412
493240324
123948532
423948234
...

But, the following code returns the IDs but in a different format:

let ids = $('[data-profileid]').map(function() {
    return $(this).attr('data-profileid')
})

console.log(ids)

Results:

...
'69': '234234234,
'70': '9328402397432',
'71': '1324235234',
  options:
   { withDomLvl1: true,
     normalizeWhitespace: false,
     xmlMode: false,
     decodeEntities: true },
  _root:
   { '0':
      { type: 'root',
        name: 'root',
        attribs: {},
...

What is all this extra data? It certainly isn't required. I'd rather just have an ordinary array.

like image 826
BugHunterUK Avatar asked Aug 19 '16 17:08

BugHunterUK


2 Answers

According to http://api.jquery.com/map/:

As the return value is a jQuery object, which contains an array, it's very common to call .get() on the result to work with a basic array.

So it looks like this should work:

let ids = $('[data-profileid]').map(function() {
    return $(this).attr('data-profileid')
}).get()
like image 157
Jack Miner Ewes Avatar answered Nov 17 '22 04:11

Jack Miner Ewes


What is all this extra data? It certainly isn't required. I'd rather just have an ordinary array.

Cheerio has a fluent API, meaning most of its functions return an object on which additional functions can be chained. If map just returned an "ordinary array" then you wouldn't be able to call additional Cheerio functions on the result. There aren't a lot of ways you can chain additional function calls onto the result of your map call, which returns an array of strings, but Cheerio's developers (taking a cue from jQuery's developers) chose to keep a consistent API rather than pepper it with special cases.

If you want an ordinary array, though, Cheerio gives you a handy toArray function:

let ids = $('[data-profileid]').map(function() {
  return $(this).attr('data-profileid')
});

console.log(ids.toArray());
// => [ '1012938412', '493240324', '123948532', '423948234' ]
like image 28
Jordan Running Avatar answered Nov 17 '22 05:11

Jordan Running