Reputation: 25
I cannot for the life of me figure out the difference between these two blocks of code:
var text = [];
$(".article-text p").each(function() {
text.push( $(this).text() );
});
And
var text = $('.article-text p').map(function() {
return $(this).text();
});
They look to me like they produce the same exact output when tested in console on the following page. However, the first one can be run by JSON.stringify
, and the second cannot.
My error message in the crawler says
Error invoking user-provided 'pageFunction': Error: TypeError: JSON.stringify cannot serialize cyclic structures.
My error message in console says:
Uncaught DOMException: Blocked a frame with origin "http://yaledailynews.com" from accessing a cross-origin frame. at JSON.stringify () at :1:6
When I compare the two objects, they look exactly the same, except that the second has a context
property. I have deleted this property but the errors still remain.
Upvotes: 2
Views: 101
Reputation: 35481
From the docs for jQuery.map
Array-like objects — those with a
.length
property and a value on the.length - 1
index — must be converted to actual arrays before being passed to$.map()
. The jQuery library provides$.makeArray()
for such conversions.
Since $('.article-text p')
will return an array-like collection (of jQuery objects), you must call $.makeArray on it:
function one() {
var text = [];
$(".test").each(function() {
text.push($(this).text());
});
return text;
}
function two() {
var text = $('.test').map(function() {
return $(this).text();
});
return text;
}
console.log(one());
// use makeArray here
console.log($.makeArray(two()));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">A</div>
<div class="test">B</div>
<div class="test">C</div>
Docs also say
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.
function one() {
var text = [];
$(".test").each(function() {
text.push($(this).text());
});
return text;
}
function two() {
var text = $('.test').map(function() {
return $(this).text();
}).get(); // <--- call get here
return text;
}
console.log(one());
console.log(two());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">A</div>
<div class="test">B</div>
<div class="test">C</div>
Upvotes: 2