I have a unique challenge:
While on URL1(random wikipedia page), make an ajax request to URL2(100 most common words wikipedia page), create array from returned data to be used later.
I have to run this from the console while on "URL1"
example:
Navigate to URL1
Open Console
paste code
hit enter
So far I have been able to get very close with the following:
$.ajax({
url: 'https://en.wikipedia.org/wiki/Most_common_words_in_English',
type: 'GET',
dataType: 'html',
success: function(data) {
Names = $.map($(data).find('.wikitable tr'), function() {
return $(this).find('td:last').text()});
console.log(Names);
}
});
But I'm getting blank values in my array.
While on URL2(link in the ajax request) the following code works perfect
var Names = $('.wikitable tr').map(function() {
return $(this).find('td:last').text() }).get(); console.log(Names);
I was gettin errors using this exact code because of the .get, after removing it, I got an array with the proper amount of elements, but they were all blank.
Thanks
Your logic is right, you are just using the wrong functions. $.map and $().map are different function with different contexts and different arguments.
Your problem should be solved if you use the correct map function. Change
success: function(data) {
Names = $.map($(data).find('.wikitable tr'), function() {
return $(this).find('td:last').text();
});
console.log(Names);
}
to
success: function(data) {
Names = $(data).find('.wikitable tr').map(function() {
return $(this).find('td:last').text();
});
console.log(Names);
}
In the second form of map, the this keyword is set to DOM element.
I also noticed that would code is returning 105 texts instead of the 100 words in the table, as it is picking the table headers too. Another cool trick of .map is that if you return null, it will not include the value in the result. Therefore, you could something like
Names = $(data).find('.wikitable tr').map(function() {
return $(this).find('td:last').text() || null;
});
as a blank string evaluates to false so the return will return null instead of ''. Or, you could just make your selector more specific, such as:
Names = $(data).find('.wikitable tr td:odd').map(function() {
return $(this).text();
});
Could you also Inspect via F12, if any error is thrown.
XMLHttpRequest cannot load https://en.wikipedia.org/wiki/Most_common_words_in_English. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Just use the Js map to iterate over Jquery Objects(Html element Object)
$(data).find('.wikitable tr').map(function() {
return $(this).find('td:last').text();
JQuery map Works only on primitives Array not on object
$.map($(data).find('.wikitable tr'), function() {
return $(this).find('td:last').text();
});
Related
Edited2: Here is a pic of how one object looks like. All fields for all objects are filled.
Edited: So the problem appears to be the each loop. I console.logged data and it showed it in an array style. But for some reason, when i try to print the object's age, f.ex., it shows up as undefined.
I am doing a small script for displaying information from a json-file with jquery and ajax. I got the ajax part working (I think) but I can't get my function to print the JSON object data.
So I am trying to display JSON object's with Jquery but it doesn't do anything. The ready function prints out done and complete.
$(document).ready(function(){
$.ajax({
url: "file.json",
cache: false
}).done(function(data) {
console.log("done");
showData(data);
}).fail(function() {
console.log("error");
}).always(function() {
console.log("complete");
});
});
function showData(data) {
$.each(data.cats, function(index, kitty) {
var div = $("<div></div>");
div.addClass("catContainer");
var image = $("<img></img>");
image.addClass("catImage");
image.src="kitty.image";
var header = $("<p></p>").text(kitty.color);
header.addClass("header");
var age = $("<p></p>").text(kitty.age);
var text = $("<p></p>").text(kitty.text);
text.addClass("text");
var price = $("<p></p>").text(kitty.price);
div.append(image,header,size,text,price);
$("div#cats").append(div);
});
}
I also tried this loop but it prints 'undefined' to the div:
$(data).each(function(i, kitty) {
$('#cats').append(kitty.price);
// I am sorry, I am noob. Hope this post is according to the instructions.
One issue is with your image.src. When you set it to "kitty.image", this would literally assign that string. So instead of:
image.src = "kitty.image",
Use:
image.attr("src", kitty.image);
Or:
image[0].src = kitty.image
The latter here, since image is a jQuery Object, would not have src as an index. So we can call image[0] to get the HTML Element, that we can then assign the src.
Consider the following.
$(function() {
function showData(d, o) {
$.each(d, function(index, kitty) {
console.log("Adding Kitty", kitty);
var div = $("<div>", {
class: "catContainer"
}).appendTo(o);
$("<img>", {
class: "catImage",
src: kitty.image
}).appendTo(div);
$("<p>", {
class: "header"
}).html(kitty.color).appendTo(div);
$("<p>").html(kitty.age).appendTo(div);
$("<p>", {
class: "text"
}).html(kitty.text).appendTo(div);
$("<p>").html(kitty.price).appendTo(div);
});
}
$.ajax({
url: "file.json",
cache: false,
success: function(data) {
showData(data.cats, "#cats");
console.log("Success");
},
error: function(x, e, n) {
console.log("Error", x, e, n);
}
});
});
Based on your post, data is an Object. data.cats is an Array of Objects. So we will iterate the Array with $.each() using data.cats. I also pass in the target object ID. .appendTo() accepts a few items:
A selector, element, HTML string, array of elements, or jQuery object; the matched set of elements will be inserted at the end of the element(s) specified by this parameter.
See More: https://api.jquery.com/appendto/
It is then just a matter of creating each of the elements. With the $("<div>"), jQuery will handle wrapping the element for us. We can also pass in an Object with the attributes, like class. We can chain to the jQuery Object that is the result and would advise using .html() versus .text(), yet there is nothing wrong with doing either.
I have a problem with jQuery ajax.
I have javascript
<script type="text/javascript">
$(function() {
$('body').on("click", "#pager a", function(e) {
e.stopPropagation();
e.preventDefault();
var a = $(this);
var model = $('#searchForm').serialize();
$.ajax({
url: '/Product/Products',
type: 'POST',
data: {
model: model, page: a
},
success: function (data) {
alert('success');
$('#productsList').html(data);
}
});
});
});
</script>
This code produce error "Uncaught RangeError: Maximum call stack size exceeded" and I don't understand why. I have no trigger, I used preventDefault and stopPropagation, but I still have this error. Can anyone help me?
This error can also come if you are passing something in data which is not defined in that scope.
Another reason is passing in data with val() directly.
Instead of using var a = $(this) to get the page, use one hidden field and give page value to the field.
<input type="hidden" value="xyzpage" id="pageValue">
var pageVal = $("#pageValue").val();
data: {
model: model, page:pageVal
},
This will solve the issue I guess
I want to share my experience,
in my case, it was only a wrong parameter name and exactly the same error message :
instead of confID, I put the configID and got this error.
function openNameEditor() {
var confID = $("#configStatusList").attr("data-id");
debugger;
$.ajax({
url: '#Url.Action("GetModelNameToChange", "Admin")',
type: "GET",
dataType: "HTML",
data: { configID: configID},//Here, instead of confID, I put configID which doesn't exist in the function.
success: function (response) {
$("#name-editor").html(response);
},
error: function (er) {
alert(er.error);
}
});
}
You need to take off the var a = $(this);. I don't know what you try to achieve there but using a the jQuery wrapped clicked element as request data is a non-sense.
Endless loop can also cause this kind of error. View that you don't call same function inside function.
I ran into such a problem when parsing a large piece of JSON using jquery.tmpl.js. This error appears when handling large arrays with the concat() function. Here is a link to the problem: https://bugs.chromium.org/p/chromium/issues/detail?id=103583
The problem has not been solved since 2011. To solve it, I had to edit the jquery-3.3.1.js javascript library file. For those who want to repeat this decision, do the following: find the following line in the library file return concat.apply ([], ret); and replace it with the code below.
// Flatten any nested arrays
if ([].flat) return ret.flat();
var ret2 = [];
ret.forEach(function (i) {
if (i instanceof Array) {
i.forEach(function (i2) {
ret2.push(i2);
});
} else {
ret2.push(i);
}
});
return ret2;
// original code:
// return concat.apply([], ret);
// chrome bug: https://bugs.chromium.org/p/chromium/issues/detail?id=103583
We check if there is a flat() function in the browser's arsenal, for example, it has a chrome browser, and if there is - simply merge the data arrays - nothing more is needed. If not, the browser will go a slower path, but at least there will be no error.
I don't know what is wrong with my code. I am trying to delete a specific row by the object ID in Parse. Right now, it's giving me a "error" in the console. I am not sure how to fix it. Thanks!
var rowId = Parse.Object.extend("Assignment");
var queryRemove = new Parse.Query(rowId);
var obj = $(elem).parent();
queryRemove.get("$(elem).parent().attr('id')", {
success: function(obj) {
console.log(obj + " got it");
obj.destroy({
success: function() {
console.log("Deleted!");
},
error: function () {
console.log("Deleted fail!");
}
});
},
error: function(obj ,error) {
console.log("error");
}
});
From the console log it is obvious that queryRemove.get is failing as you see error handler processed.
According to Parse Api reference you should be passing a string id to query.get(), so I suppose you've mistaken in the parameter. JQuery should be evaluated and .get should receive id of an element not a string "$(elem).parent().attr('id')" which is obviously not a good id
queryRemove.get($(elem).parent().attr('id'), {
Also doesn't look like you can delete an item with .get()... Have analysed parse.com api before using it?
I am trying to return data from a database and populate a text field after the user enters an ID in the first text box. Currently I had the code working as long as the user did not enter a space in the ID number. Now I am attempting to allow that use case. My PHP code returns a json encoded array with three fields: first_name, last_name, and full_name.
When I use console.log(data) to view the data being returned I receive the following:
{"first_name":"Test","last_name":"Test","full_name":"Test Test"}
However in my code, I try to write data.full_name in a .val() nothing is populated, and when use the console.log I get an error saying "undefined".
Here is the whole jQuery Code:
$("#ID").blur(function () {
var params = {};
params.ID = encodeURIComponent($(this).val());
$.post("getter.php", params, function ( data ) {
if (!data) {
$("input[name=username]").val("User Not Found");
} else {
$("input[name=username]").val(data.full_name);
$("input[name=username]").attr("readonly", true);
}
});
});
Any help you can offer would be much appreciated.
Force jQuery to read the returned data as json:
$("#ID").blur(function () {
var params = {};
params.ID = encodeURIComponent($(this).val());
$.post("getter.php", params, function ( data ) {
if (!data) {
$("input[name=username]").val("User Not Found");
} else {
$("input[name=username]").val(data.full_name);
$("input[name=username]").attr("readonly", true);
}
}, "json"); // <- json forced
});
and then make sure your returned data is in proper json format (for example with json_encode in php)
Use trim() to remove spaces.
Then you can check if the parameter value is_numeric(), and if false, set a default value.
I want to make a custom dojo JsonRest Store, there is a part that I don't understand in the query function.
This is the part that I don't fully understand:
var results = xhr("GET", {
url: this.target + (query || ""),
handleAs: "json",
headers: headers
});
results.total = results.then(function(){
var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
return range && (range = range.match(/\/(.*)/)) && +range[1];
});
return QueryResults(results);
As far as I understand, it tries to get an array of object from the url and then append the total of records to the results which is a deferred? Can you do that? And it seems like the function returns a boolean instead of an integer.
Anyway I tried to replicate that part of code in my own way.
var result = request.post(this.target + "/get",
{
data: dojo.toJson(requestParam),
handleAs: "json",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
}
});
var results = result.then
(
function (result)
{
return (result.entities?result.entities:{});
}
);
results.total = result.then
(
function (result)
{
return result.total;
}
);
results.total.then(function(total){
console.log("total results: ", total);
});
return QueryResults(results);
But the total is undefined, I think it's because the results is a deferred not an array. I just don't get it. How do I recreate this function in my own way?
Firstly, to answer your questions about how the query method returns, yes, the total is a property on the returned value. Both the return value and total are allowed to be immediate values or promises.
In the first code you pasted, results.total will ordinarily return a number, not a boolean. return range && (range = range.match(/\/(.*)/)) && +range[1]; will first attempt to pull the contents of the Content-Range header following a forward slash, and if successful, will coerce that to a number and return it.
RE your code, you are likely finding total is undefined because dojo/request returns promises (preferable over returning full Deferreds), and promises are frozen in browsers that support ES5, which will prevent you from adding the total property to it. You will likely want to use lang.delegate to create a new object based on the promise to get around this limitation.
Also, your default value for the results should be an empty array, not an empty object.