I have a web extension that is loading content into the popup based on existing tokens, and I need it to add a click listener to a button that's dynamically added, but I can't seem to get it to add AFTER the button is inserted into the page. It keeps coming up that TypeError: document.getElementById(...) is null.
I've tried using windows.onload and DOMContentLoaded with no luck
Code
// Get and display profile
function outputProfile(ACC_TOK) {
var request = new XMLHttpRequest();
request.open('GET', 'https://private-anon-535ecb43fa-trakt.apiary-mock.com/users/settings');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Authorization', 'Bearer ' + ACC_TOK);
request.setRequestHeader('trakt-api-version', '2');
request.setRequestHeader('trakt-api-key', APP_KEY);
request.onreadystatechange = function () {
if (this.readyState === 4) {
// Get Response and put in array
var response = JSON.parse(this.responseText);
document.body.innerHTML = '<section id="traktProfile"><div id="traktAvatar"><img src="' + response.user.images.avatar.full + '" width="100px" height="100px" alt="' + response.user.name + '" /></div><div id="traktUser"><h1>' + response.user.name + '</h1><p><i class="fa fa-map-marker"></i> ' + response.user.location + '</p></div></section><section id="traktSignOut"><a id="traktSignOutLink" class="profileLink">Sign Out</a></section>';
}
};
request.send();
}
// Check if Access Token Exists
chrome.storage.local.get("access_token", function (result) {
if (result.access_token && typeof result.access_token !== undefined) {
// Output Profile Page
outputProfile(result.access_token);
// Sign out button
window.onload = function() {
console.log("DOM Loaded");
document.getElementById("traktSignOutLink").addEventListener("click", traktSignOut);
};
} else {
// Output Authenctication Page
outputAuth();
}
});
parden me if i get the wrong idea
why don't you add click here
document.body.innerHTML = '<section id="traktProfile"><div id="traktAvatar"><img src="' + response.user.images.avatar.full + '" width="100px" height="100px" alt="' + response.user.name + '" /></div><div id="traktUser"><h1>' + response.user.name + '</h1><p><i class="fa fa-map-marker"></i> ' + response.user.location + '</p></div></section><section id="traktSignOut"><a id="traktSignOutLink" class="profileLink" onclick="traktSignOut();">Sign Out</a></section>';
I ended up linking it to another page and running the script from there
Popup.js
// Get and display profile
function outputProfile(ACC_TOK) {
var request = new XMLHttpRequest();
request.open('GET', 'https://private-anon-535ecb43fa-trakt.apiary-mock.com/users/settings');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Authorization', 'Bearer ' + ACC_TOK);
request.setRequestHeader('trakt-api-version', '2');
request.setRequestHeader('trakt-api-key', APP_KEY);
request.onreadystatechange = function () {
if (this.readyState === 4) {
// Get Response and put in array
var response = JSON.parse(this.responseText);
document.body.innerHTML = '<section id="traktProfile"><div id="traktAvatar"><img src="' + response.user.images.avatar.full + '" width="100px" height="100px" alt="' + response.user.name + '" /></div><div id="traktUser"><h1>' + response.user.name + '</h1><p><i class="fa fa-map-marker"></i> ' + response.user.location + '</p></div></section><section id="traktSignOut">Sign Out</section>';
}
};
request.send();
}
// Check if Access Token Exists
chrome.storage.local.get("access_token", function (result) {
if (result.access_token && typeof result.access_token !== undefined) {
// Output Profile Page
outputProfile(result.access_token);
} else {
// Output Authenctication Page
outputAuth();
}
});
Signout.js
window.onload = function () {
// Get Access Token to clear
chrome.storage.local.get("access_token", function (result) {
// Revoke Token
var request = new XMLHttpRequest();
request.open('POST', 'https://private-anon-535ecb43fa-trakt.apiary-mock.com/oauth/revoke');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Authorization', 'Bearer ' + result.access_token);
request.setRequestHeader('trakt-api-version', '2');
request.setRequestHeader('trakt-api-key', APP_KEY);
request.onreadystatechange = function () {
if (this.readyState === 4) {
if (this.status === 200) {
// Clear Storage
chrome.storage.local.clear(function() {
// Alert user
chrome.runtime.sendMessage({"type": "notification", "title": "Trakt for IMDb Signed Out", "content": "You have been logged out of Trakt for IMDb."});
// Redirect back to popup.html
setTimeout(function () {
window.location.replace("index.html");
}, 800);
});
} else {
// Alert user
chrome.runtime.sendMessage({"type": "notification", "title": "Trakt for IMDb Sign Out Error", "content": "Sorry there was an issue signing you out of Trakt for IMDb. Please try again."});
// Redirect back to popup.html
setTimeout(function () {
window.location.replace("index.html");
}, 800);
}
}
};
var body = {'access_token': result.access_token};
request.send(JSON.stringify(body));
});
};
This may be messy, but it does the trick for me. If anyone works out an easier/better answer I'm all ears :D
Related
I am trying to perform a delete operation, to delete an item from user's favorites but am having a hard time figuring our how to retrieve restaurant_name.
In POSTMAN my delete operation url is {{baseUrl}}/favorites/restaurant_name/user_name
Currently I can retrieve the user_name of logged in user from session storage
I tried many ways to retrieve the restaurant_name.
One way I tried was to store it in the URL and tried to retrieve it from there but it did not work.
I also tried to store the restuarant_name in session storage when I click the button but that did not work either. The value for restaurant_name did not show up in session_storage.
As u can see from the image bottom left hand corner, the restaurant_name can be retrieved in the URL. However when I try to console.log(restaurant_name) it says its undefined the first time as it has not gone to the URL with restaurant name yet (e.g localhost3000/favorites.html?restaurant_name=Astons). Afterwards going to the URL it is able to retrieve the restaurant_name from the URL.
This is my code for reference. Any help will be appreciated :)
Get Favorites
function getFavorites() {
var response = "";
var request = new XMLHttpRequest();
user_name = sessionStorage.getItem('user_name');
request.open("GET", "https://abakandkansdjk.execute-api.us-east-1.amazonaws.com/favorites/" + user_name, true);
request.onload = function () {
response = JSON.parse(request.responseText);
console.log(response);
var HTML = ""
for (let i = 0; i < response.Count; i++) {
console.log(response.Items[i].restaurant_name)
HTML += '<div class="col-md-3 box " style="background-color: #debc99;">' +
'<div class="card" style="margin:15px -5 20px -5; ">' +
'<a class="card-block stretched-link" href="#"></a>' +
'<img class="card-img-top" src="' + response.Items[i].image + '" style="margin-left: 1px;width: 220px; margin-top: -15px;"' +
'alt="Card image cap">' +
'<div class="card-body">' +
'<h5 class="card-title"></h5>' +
'<h4 style="margin-top: 0px; color:black">' + response.Items[i].restaurant_name + '</h4>' +
'<span class="badge badge-secondary float-right"' +
'style="background-color: #8d4843; margin-top: -5px;">Cuisine</span>' +
'<a style="color: black; margin-top: -5px;" onclick="deleteFavorites(); sessionStorage.setItem("favRestaurant",' + response.Items[i].restaurant_name +');" href="favorites.html?restaurant_name=' + response.Items[i].restaurant_name + '"' + '><u>Delete</u></a>' +
'</div>' +
'</div>' +
'</div>'
}
document.getElementById('favoritesList').innerHTML = HTML;
};
request.send();
}
Delete Favorites
function deleteFavorites() {
var response = "";
var user_name = sessionStorage.getItem("user_name")
console.log(user_name)
var alert1 = confirm("Are you sure you want to delete this item from your favourites? This is irreversible.");
if (alert1 === true) {
window.location.href="http://localhost:3000/favorites.html?restaurant_name=" + restaurant_name
console.log(restaurant_name)
var urlParams = new URLSearchParams(window.location.search);
var restaurant_name = urlParams.get("restaurant_name");
var request = new XMLHttpRequest();
var url = "https://aba3bajndc.execute-api.us-east-1.amazonaws.com/favorites/" + restaurant_name + "/" + user_name
console.log("restaurant_name")
request.open("DELETE", url, true);
request.onload = function () {
if (response.message == "favorites deleted") {
alert('This restaurant has been deleted from favorites!');
}
else if (response.message != "favorites deleted") {
alert('Unable to add to favorites, try again!');
}
}
request.send();
}
}
I would change onclick="deleteFavorites(); to:
onclick="deleteFavorites(response.Items[i].restaurant_name);
And change the deleteFavorites function signature to be:
function deleteFavorites(restaurant_name) {
In function readyStateChangeHandler(xhttp), my website (which returns a table) outputs both results of the handler, success and failure, even though the table is being displayed with no problems at all.
Notice below the "get search result" button, an error is being displayed from readyStateChangeHandler
function makeAjaxQuery() {
// create an XMLHttpRequest
var xhttp = new XMLHttpRequest();
// create a handler for the readyState change
xhttp.onreadystatechange = function() {
readyStateChangeHandler(xhttp);
};
// making query by async call
xhttp.open("GET", "xxxxxxx-A3-Q6.json", true);
xhttp.send();
}
// handler for the readyState change
function readyStateChangeHandler(xhttp) {
if (xhttp.readyState == 4 && xhttp.status == 200) {
// readyState = 4 means DONE
//status = 200 means OK
handleStatusSuccess(xhttp);
console.log('success')
} else {
// status is NOT OK
console.log('failure')
handleStatusFailure(xhttp);
}
}
// XMLHttpRequest failed
function handleStatusFailure(xhttp) {
//display error message
var displayDiv = document.getElementById("display");
displayDiv.innerHTML = "XMLHttpRequest failed: status " + xhttp.status;
}
// XMLHttpRequest success
function handleStatusSuccess(xhttp) {
var jsonText = xhttp.responseText;
//parse the json into an object
var obj = JSON.parse(jsonText);
// display the object on the page
displayObj(obj);
}
function displayObj(obj) {
var table = "";
for (i = 0; i < 5; i++) {
table +=
"<tr><td>" + '<img src="' + obj.result.video[i].image + '" width=200"' + '' + "</td><td>" +
'<span style="color:#DA3FA4; font-weight:bold; font-size: 30px;">' + obj.result.video[i].title + "</span>" + "<br/>" +
'<span style="font-weight:bold;font-size: 25px;">' + obj.result.video[i].channel + "</span>" + "<br/>" +
'<span style="font-weight:bold;font-size: 25px;">' + obj.result.video[i].view + " views" + "</span>" + "<br/>" +
'<span style="font-weight:bold; background-color: black; color:white"font-size: 25px;>' + obj.result.video[i].length + "</span>" + "</td></tr><td>";
}
document.getElementById("test").innerHTML = '<h1>Search results</h1><br><span style="font-size: 30px;">Search keyword: Mathematics</span><br>';
document.getElementById("demo").innerHTML = table;
}
const start = document.getElementById("getSearch");
start.addEventListener("click", function() {
makeAjaxQuery()
});
I would guess you get something in between the if (xhttp.readyState == 4 && xhttp.status == 200) { for example 2 or 3 plus 200 readystate - so for example use
xhttp.onload= function() {
readyStateChangeHandler(xhttp);
};
or fetch
I wrote the following code and the ciso variable is defined and its value is displayed when the code is executed, but when the find_cites function is executed, it shows the Uncaught ReferenceError: x is not defined error.
function find_states(ciso){
var request = new XMLHttpRequest();
request.open('GET', 'https://api.countrystatecity.in/v1/countries/' + ciso + '/states');
request.setRequestHeader('xx', 'xx');
request.onreadystatechange = function () {
if (this.readyState === 4) {
// console.log('Status:', this.status);
// console.log('Headers:', this.getAllResponseHeaders());
// console.log('Body:', this.responseText);
var items2 = JSON.parse(request.responseText);
var output2 = "<select name='state' class='form-select' aria-label='Default select example' style='width: 50%;margin-right: 5%;'>";
// document.getElementById("test").innerHTML = items2;
for(var key in items2){
console.log(items2[key]);
output2+='<option onclick="find_cites(' + ciso + ',' + items2[key].iso2 + ')">' + items2[key].name + '</option>';
}
output2+="</select>";
document.getElementById("state").innerHTML = output2;
// console.log(ciso);
}
};
request.send();
};
function find_cites(ciso,siso){
var request = new XMLHttpRequest();
equest.open('GET', 'https://api.countrystatecity.in/v1/countries/' + ciso + '/states/' + siso + '/cities');
request.setRequestHeader('xx', 'xx');
request.onreadystatechange = function () {
if (this.readyState === 4) {
// console.log('Status:', this.status);
// console.log('Headers:', this.getAllResponseHeaders());
// console.log('Body:', this.responseText);
var items2 = JSON.parse(request.responseText);
var output2 = "<select name='city' class='form-select' aria-label='Default select example' style='width: 50%;margin-right: 5%;'>";
// document.getElementById("test").innerHTML = items2;
for(var key in items2){
console.log(items2[key]);
output2+="<option>" + items2[key].name + "</option>";
}
output2+="</select>";
document.getElementById("city").innerHTML = output2;
// console.log(ciso);
}
};
request.send();
};
You've got possible error here:
equest.open('GET', 'https://api.countrystatecity.in/v1/countries/' + ciso + '/states/' + siso + '/cities');
Should be:
request.open('GET', 'https://api.countrystatecity.in/v1/countries/' + ciso + '/states/' + siso + '/cities');
The ciso variable is a string and must be enclosed in quotation marks ('') when entering the function, but this was ignored when passing data to the function, and the error was related to this point.
The following codes are illustrative:
Old code:
output2+='<option onclick="find_cites(' + ciso + ',' + items2[key].iso2 + ')">' + items2[key].name + '</option>';
New code:
output2+='<option onclick="find_cites(' + "'" + ciso + "'" + ',' + "'" + items2[key].iso2 + "'" + ')">' + items2[key].name + '</option>';
I've tried to perform AJAX request, but I've got this kind of error, that ajax call should be opened. But it is opened already. Trying to send the XMLHttpRequest header, but getting this kinda error. Guys, help me!
let del_btn = document.querySelectorAll('.delete');
for(let i = 0; i < del_btn.length; i++)
{
del_btn[i].addEventListener('click', function(){
let xhr = new XMLHttpRequest();
let book_title = del_btn[i].parentElement.children[1].children[1].children[0].children[0].textContent;
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
if(this.responseText.includes('Deleted'))
{
let books = this.responseText.split('.')[1];
if(books == '0')
{
del_btn[i].parentElement.parentElement.innerHTML = 'You have no books in your list. Go to the ' + ' ' + ' main page ' + ' ' + 'and start your ride!';
}
else
{
del_btn[i].parentElement.parentElement.removeChild(del_btn[i].parentElement);
document.querySelector('.amount-b').textContent = 'Количество книг: ' + books;
}
}
}
}
xhr.open("POST", "../operations/delete_book.php", true);
xml.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('title=' + book_title);
}, false);
}```
I'm trying to create a site in which, through the Spotify Web API, I display the information of a certain element (Artist, Track, Album, etc ...).
I was trying to make a check on the url of the profile image of the Artist object as it is not said to be present, but when the console runs it gives me the error "Unexpected token }".
Could someone help me on why?
Below I leave the code:
function ricercaArtista() {
var xhr = new XMLHttpRequest();
var token = document.getElementById("token").innerHTML;
var artist = document.getElementById("artista").value;
artist = artist.replace(" ", "%20");
console.log(artist);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var response = JSON.parse(xhr.responseText);
var result = '';
for (var i = 0; i < response.artists.items.length; i++) {
console.log(response.artists.items[i]);
try { //from here start the control on the image
result += '<div class="panel panel-primary style="background:url(' +
response.tracks.items[i].album.images[1].url + '");"><div class="panel-body">' +
} catch (error) {
result += '<div class="panel panel-primary");"><div class="panel-body">' +
}
'name : ' + response.artists.items[i].name + '<br/>' +
'popularity : ' + response.artists.items[i].popularity + '<br/>' +
'type : ' + response.artists.items[i].type + '<br/>' +
'' + 'Apri su Spotify' + '<br></div></div>';
}
alert
document.getElementById("artists").innerHTML = result;
}
};
xhr.open('GET', "https://api.spotify.com/v1/search?q=" + artist + "&type=artist", true);
xhr.setRequestHeader('Accept', 'application/json');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Bearer ' + token);
xhr.send();
}