question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

map returns array instead of Cheerio object

See original GitHub issue

In jQuery, $(selector).map(callback) will return a jQuery object wrapping return values of callback. In Cheerio, we instead get back an array, each element of which is a length-1 Cheerio object wrapping a return value of callback.

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
jugglinmikecommented, Jan 6, 2019

Convert the collection to a JavaScript array first:

$('div').map(($el) => {
  // $el is a Cheerio object
});

$('div').toArray().map((el) => {
  // el is a node
});

Note that the return value will also be an array, though!

0reactions
discopatrickcommented, Aug 11, 2019
  1. It’s consistent with jQuery (therefore portable and familiar). I still maintain that making jQuery code portable is a valid use case for this project.
  2. It’s more efficient–not all users will need Cheerio instances, and those that do can create a Cheerio object from the nodelike themselves: var $elem = Cheerio(this);

Hi @jugglinmike - I’m in agreement with the two points you make. However, I would like to ask for some advice on how to implement your point 2.

Firstly I’m assuming that Cheerio in your example is the result of cheerio.load(html); (given that const cheerio = require('cheerio')), which would have been executed at some point before moving into the map callback.

Given that assumption, in order to rewrap the node in a cheerio object doing var $elem = Cheerio(this); as you describe, I would need to have the Cheerio var in scope, or alternatively have the original html var in scope so that I could recreate the Cheerio object with another cheerio.load(html);. Unfortunately in my code I have neither of these vars in scope at the time I wish to do this. Thus, I am using this little hack:

// inside a class

startHere() {
  const html = '<html>...</html>' // loaded from disk in reality
  const $ = cheerio.load(html);
  const $interesting = $('div#interesting');
  this.doSomething($interesting);
}

doSomething($interestingElement) {
  // note that neither `$` nor `html` are in scope here
  $spans = $interestingElement.find('span');
  $spans.map((i, el) => {
    const $ = cheerio.load(''); // here's the hack - call `load` with empty string
    const $el = $(el);
    // do something with $el now that it's wrapped in a cheerio object
  });
}

This seems to work fine. It just feels a little messy that I should need the hack. Can you think of a better way?

One solution might be to have $ as a member of the class rather than creating it in startHere() so that I can call upon it with this.$, although the issue there is that this class works on multiple html documents (with different values of html) so if I call this.$ = cheerio.load(html); I would overwrite the previous value. That said, generally I do these operations in series and not in parallel, so perhaps it would be fine.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cheerio Map Strange Behaviour - node.js - Stack Overflow
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 ...
Read more >
How to use map function in Cheerio - Javascript - Tabnine
function parseHTML (html, selector) { const $ = cheerio.load(html) return $(selector) .map(function () { return ($(this).html() || '').replace(/\s+/g, ...
Read more >
Extracting data with Cheerio | Algolia
Learn the Cheerio syntax to extract data in the Algolia Crawler, and discover ready-to-use selectors and extractors.
Read more >
Class Cheerio<T> Abstract
Returns a copy of a section of an array. For both start and end, a negative index can be used to indicate an...
Read more >
How To Use .map() to Iterate Through Array Items in JavaScript
One of the most popular methods is the .map() method. .map() creates an array from calling a specific function on each item in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found