I am trying to make a chrome extension which fetches IDs of Youtube videos, but am facing a problem. For first execution, the AJAX call gives me an error, but for all subsequent calls, works just fine. This happens every time I open the extension. I am new to the scene, and hence, please excuse me for any rookie mistakes. My code :-
function getIDs(data){
var items = [];
for(i in data.items){
items.push(data.items[i].id.videoId.toString());
}
for(i in items){
$('<p>'+items[i]+'</p><br>').appendTo('#results');
}
}
function getVideo(searchQuery){
searchQuery = searchQuery.replace(/ /g,'+');
var queryURL = 'https://www.googleapis.com/youtube/v3/search?q='+searchQuery+'&key=AIzaSyDq5SqWuQIEfIx7ZlQyKcQycF24D8mW798&part=snippet&maxResults=3&type=video';
$.ajax({
url: queryURL,
dataType: 'json',
success: function(data) {
getIDs(data);
},
error: function(ts){
alert(ts.responseText);
}
});
}
document.addEventListener('DOMContentLoaded',function(){
var button = document.getElementById('search');
var div = document.getElementById('results');
button.addEventListener('click',function(){
var input = document.getElementById('input');
var result = input.value;
getVideo(result);
});
});
I can't for the life of me figure out what is wrong. Thanks for the help in advance.
EDIT
I forgot to mention, but it gives me an undefined error. Sorry !!
I tried your Chrome extension and managed to replicate this behaviour.
The problem is in the following code:
<form action="#">
<input type="text" id="input"><br><br>
<center><button id="search">Click Here!!</button></center>
</form>
Upon clicking the search button, the form is being submitted and reloading the page. The page reloads so your AJAX request is cancelled. This is what what giving you the readyState 0 error. One way you can tell this is happening is by noticing that the text from the text input disappears when you press the button.
To stop the reloading, you could use e.preventDefault() in the JavaScript like the page above suggests, but I think the most appropriate solution here is to add type="button" to your button:
<button id="search" type="button">Click Here!!</button>
You may wonder why this only happened on the first request. This comes down to how action="#" is handled and the answer is basically, not in any standard way that you can rely on. In fact, you can test here and see that Firefox doesn't reload the page at all, whereas Chrome does, but only the first time.
Your problem seems to be that the data you're retrieving doesn't load in time in the first execution since AJAX calls are asynchronous. So when you call getIDs(data), data might not be loaded yet (which is why it's working on the subsequent calls).
One way you can resolve this issue is by using a promise. Rather than using success, you can do something like this:
var ids;
$.ajax({
url: queryURL,
dataType: 'json',
success: function(data) {
ids = data;
},
error: function(ts){
alert(ts.responseText);
}
}).then(function(){
getIDs(ids); //calls this function *after* the data is retrieved
});
This post on StackOverflow does a good job of explaining it.
Related
I have the following program in which a user can enter any name in a search box after which I redirect the user to a page called usernameSearchResults.php where I print a list of the usernames obtained in the form of an array from usernamesearch.php. Here is the javascript:
$(window).on('load', function() {
$(".searchBarForm").submit(function(e){
e.preventDefault();
var search=document.getElementsByClassName("search")[0].value;
$.ajax
({
type: 'POST',
url: 'usernamesearch.php',
data:
{
search:search
},
success: function (response)
{
window.location.href="usernameSearchResults.php";
response = JSON.parse(response);
var array_length = Object.keys(response).length;//getting array length
for(var i=0;i<array_length;i++){
if(i==0){
document.getElementById("searchResults").innerHTML=""+response[0].username+"<br>";//i=0
}else{
document.getElementById("searchResults").innerHTML+=""+response[i].username+"<br>";
}
}
window.stop();//stops page from refreshing any further(put here to fix a bug that was occuring)
},
error: function(xhr, status, error) {
alert(xhr.responseText);
}
});
return false;
})
});
This is usernameSearchResults.php(inside tags):
<h1>Username Search Results</h1>
<p id="searchResults"></p>
But the problem is that whenever I go to any other page say index.php and enter the username to be searched, the page redirected to is indeed usernameSearchResults.php but the page is blank and error in the console shown says document.getElementById("searchResults") is null.But if I stay at the page usernameSearchResults.php and refresh it and then search any name again, then the results are correctly obtained. What is the problem here?
I would say that the user is being redirected to usernameSearchResults.php but the JavaScript code is still being executed from the current page, which have no element with id "searchResults" defined.
As #Kashkain said, one way to achieve what you want is to pass your response variable in your redirection url and process it then into your other page.
I think the problem here is that the new document could very well still not have been loaded when you call getElementById.
You could add a listener on your target element which would trigger on the load event. In this event's handler you could execute the operations that are now giving you an error.
I have never done or tried this, but maybe something like this would work:
$('#searchResults').on('load', function() {
//execute code here
});
Or you could add a form to the page with action="target_url" method="post" and send your response data through post by doing form.submit, and place the problematic code into usernameSearchResults.php, which will need to read data from POST - this way you can send your ajax data to the new page
I've seen several questions here with the similar subject but I can't find anything which is relevant to my situation. I am trying to build jQuery code that is able to build a list of items to save it in an inventory database and I am using .post() those to a additems.php that will add them to that database (after sensitization), as well as the current path name so the .php can send the user back to the same page.
The behavior I am getting is nothing whatsoever with no console error (except the 'this works' alert when I leave that in.) The behavior I am looking for is, the page should redirect to additems.php as an html form action would, execute the code there and redirect back to this page.
Here is my piece of code:
$(document).ready(function(){
$("#button").click(function(){
alert("this works");
var itemsarray = ['itemname'];
var itemattributesarray = ['itemattribute'];
var quantitiesarray = ['1'];
$.post('additems.php', {
items:{items: itemsarray},
itemattributes:{itemattributes: itemattributesarray},
quantities:{quantities: quantitiesarray},
returnpath: window.pathname
});
});
});
Thank you for your time and any suggestions. I've never used this site so please let me know how I can improve my question as well, if you have the time.
An alternative way is,
$.ajax({
'url':'additems.php',
'method' : 'POST',
'data':{
'items':itemsarray,
'itemattributes':itemattributesarray,
'quantities' : quantitiesarray
},
success: function(data){
//here you will get ajax response
console.log(data);
}
});
Preface
For this question, I have a MVC partial view. The view has a section which displays a list of documents. Each document has a hyperlink: when clicked, the hyperlink takes the user to a second page view displaying additional information.
The link is inside an unordered list:
<a style="text-decoration:underline;" onclick="sendToDocketSearch('#currentDocument.DktYear','#currentDocument.DktSequence','#currentDocument.DktSubActionID');">#currentDocument.DktYear.ToString().PadLeft(2, '0') - #currentDocument.DktSequence.ToString().PadLeft(5, '0')</a>
When the user clicks the link, it takes them to a sendToDocketSearch javascript function (to prepare to search for the document):
var sendToDocketSearch = function (yearOfDocket, sequenceOfDocket, dktSubActionIDOfDocket) {
jQuery.ajax({
type: "POST",
url: "#Url.Action("DocketSearchOnDemand")",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ docketYear: yearOfDocket,
docketSequence: sequenceOfDocket,
DktSubActionID: dktSubActionIDOfDocket,
userIsAuthorized: '#Model.userIsAuthorized' }),
success: function (data) {
alert(data);
},
failure: function (errMsg) {
alert(errMsg);
}
});
submitForm();
}
Note that the page/view/form is submitted after the following controller method is run:
public ActionResult DocketSearchOnDemand(string docketYear, string docketSequence, decimal DktSubActionID, bool userIsAuthorized, PortalIndexView viewmodel)
{
System.Web.HttpContext.Current.Session.Add("userIsAuthorized", userIsAuthorized);
string docketSearch = docketYear + "-" + docketSequence;
System.Web.HttpContext.Current.Session["DocketSearchOnDemand"] = docketSearch;
if (DktSubActionID > 0)
{
System.Web.HttpContext.Current.Session["DktSubActionID"] = DktSubActionID.ToString();
System.Web.HttpContext.Current.Session["searchingCustomID"] = true;
}
else
{
System.Web.HttpContext.Current.Session["DktSubActionID"] = "1";
System.Web.HttpContext.Current.Session["searchingCustomID"] = false;
}
return View(viewmodel);
}
The above controller method runs; then, because the form is submitted, the HttpPost action for the page takes place. When running it on my local PC, the link is clicked and the next page is loaded without drama.
Problem
The problems start when I upload the code to the dev/test server. I don't know how to use breakpoints while troubleshooting an active website, so I follow along with the browser developer tool to monitor network traffic.
When clicking the link when running the website on my localserver, the process continues:
the hyperlink takes me to a method where I pass information to be searched
the page/view/form is submitted
the controller redirects where I have to go.
When I click the link on the site and it's on the server, the first click is completely ignored - network traffic shows that it tries to navigate to the controller via the javascript function above, but the failure happens so fast I can't even take a screenshot of it. The page reloads a second time at this point.
When I click on the same link a second time, it works without fail.
I believe the view/javascript/controller code works because it works the second time (and on subsequent attempts). It just flagrantly fails the first time on the server; after that, the user is fine. I'd like to prevent that "first-time" failure, however, and I'm wondering what the problem could be...
Bad timing
I may be passing the information too early (or too late for my website/server to process it properly). The page does it correctly the second time, so maybe I'm just "jumping the gun" by not waiting a little longer for page-loading processes to sort themselves out. (Maybe I can fiddle around with the $(document).ready() javascript portion of the first page to "delay" allowing people to click a link.)
Code error
I'll be glad to admit bad code if I'm genuinely messing something up. Maybe it's my javascript function, or maybe it's the code in my controller; at any rate, something is making the first pass of that function call be rejected. Maybe my code is bad because the problem doesn't happen the second time, and I'm getting a false sense of security (i.e. there are problems with my code that the system is willing to forgive after the page has thoroughly loaded).
Server problem/miscellaneous
I'm wondering if I missed something when I uploaded my latest changes, or if I should have contacted my network team in case there are permissions that need to be activated for the site to work smoothly. I'm already in touch with them regarding something else, so I might take advantage of the opportunity today.
There is an alternative in place that could help me prevent this problem from happening, but I want to find out why the "first-time" failure happens. Other similar actions fail the first time on the site, and I'd like to apply the insights from fixing this issue to them.
Thank you for looking at this issue. Have a great day.
Are you sure you want to call submitForm(); before your jQuery.ajax has finished? your ajax call is async so it will hit submitForm(); before it has had time to finish. should submitForm(); be in your success event instead?
Once the validation runs, fails, and proceeds to redirect to the same controller index.
if (!$this->form_validation->run())
{
$this->index();
}
The form is a simple, two dropdowns, one dependent on the other, once the view is reloaded though, the second dependent dropdown stops working.
Here is the JS
$(document).ready(function()
{
$('#manufacturer_dropdown').change(function()
{
$("#sw_names > option").remove();
var id = $('#manufacturer_dropdown').val();
$.ajax({
type: "POST",
url: "software/get_software_names/"+id,
datatype : "JSON",
success: function(sw_names)
{
$.each(sw_names,function(id,software_name)
{
var opt = $('<option />');
opt.val(software_name);
opt.text(software_name);
$('#sw_names').append(opt);
});
}
});
});
});
If I manually refresh the page, the dropdowns work again. Not sure what is happening, maybe the document ready function stops checking or something. I'm no JS expert...
I can post more of the code if needed.
Edit: My JS URL was missing a /
Works now
If you are making an ajax request, you must give an ajax response
You cannot redirect the page in the middle of a request like that.
I've written something up going through all of this type of problem, as it's such a common one. Hopefully this will steer you along: http://codebyjeff.com/blog/2013/04/how-do-i-use-ajax-with-framework-x
A quiz form is completed by the user and the "Score Quiz" link is clicked. What is wanted is for the score to be tallied, results sent to server via jQuery ajax call, and the fancybox presenting the user notice.
What is happening is the tally is done and the ajax call is initiated and the page reloads. If I comment out the ajax call, the fancybox appears as desired. Using Wordpress 3.4.2.
What might be going on?
jQuery('#checkQuiz').click(function(){
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
// tally correct answers
var quizData = tallyScore();
// display user notice
jQuery('a#hiddenAnchor').trigger('click');
// store the data while the user is reading the results display
jQuery.ajax({
type:"post",
url:ajaxurl,
data:quizData
});
return false;
});
NOTE 1: I was able to catch an error in the Firebug console:
NS_ERROR_XPC_NOT_ENOUGH_ARGS: Not enough arguments [nsIDOMLocation.replace]
The file reported is jQuery.js and that appears to be a version 1.7.2. I noted that jQuery current release is 1.8.1. I wonder if that is part of the problem.
NOTE 2: I forgot to mention that this code is part of page template in a child theme. Similar ajax calls made on other pages in the web app work fine. I added a post to the Wordpress.org troubleshooting forum in case someone there doesn't visit stackoverflow.
NOTE 3: I tested this with the standard theme for wordpress "twentyeleven". The same error occurred. I am running out of options to test.
You should try:
jQuery('#checkQuiz').click(function(e){
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
// tally correct answers
var quizData = tallyScore();
// display user notice
jQuery('a#hiddenAnchor').trigger('click');
// store the data while the user is reading the results display
jQuery.ajax({
type:"post",
url:ajaxurl,
data:quizData
});
e.preventDefault()
return false;
});
Using e.preventDefault should stop the page from reloading.
Note that I made two changes to your code. I added e to the parameter-list for your callback function and e.preventDefault at the end of that function.
After testing and decomposing the code involved, the error was found in the data array passed into the ajax call. To aid anyone seeking answers for a similar error here is what I found in the code.
quizData is an array structured for the WordPress ajax handler.
Code As Found
var quizData = {
action: 'save_quiz',
item: invoice_item,
lesson: jQuery("#lesson"),
score: ratio };
There are two problems with this code. First, the jQuery call is assigning a jQuery object to the array value element "lesson". This results in an "undefined" value in the array that creates the error condition. The missing bit here is the ".val()" function invocation.
The second one may be the code architecture of the project, but it appears that a jQuery call within array assembly block does not work as expected. In my tests, the data array contained an empty value.
Resolution
var lesson_id = jQuery("#lesson").val();
var quizData = {
action: 'save_quiz',
item: invoice_item,
lesson: lesson_id,
score: ratio };
I hope this helps someone.