jquery API request error/ won't show giphy's - javascript

I cannot figure out what is wrong with my code and why my API/AJAX call will not show the images that I'm calling. It appears when I console.log(results) the 10 images are called but they will not show. Here is my jquery code..
//when window loads ... function will happen
window.onload = function(){
var musiciansList = [];
var inputBox = $('#submitButton')
//whatever musician the user submits will appear
$('#submitButton').on('click', function(){
var input=$('#submitButton');
var userInput=inputBox.val();
musiciansList.push(userInput);
renderButtons();
});
function renderButtons() {
var button = $('<button>');
button.text(musiciansList[musiciansList.length-1]);
button.addClass('band')
$('.container').append(button);
};
//When I click this button a function will happen
$(document).on('click', '.band', function() {
//variable queryUrl for giphy
var queryUrl = "http://api.giphy.com/v1/gifs/search?q=music&api_key=dc6zaTOxFJmzC&limit=10";
//requesting information giphy
$.ajax({
url: queryUrl,
method: 'GET'
})//recieving information from giphy
.done(function(response) {
//returns the response from the website
var results = response.data;
var imageUrl = response.data.image_original_url;
var musicians = $('<img>');
console.log(queryUrl)
//takes var musicians and adds attr src and imageUrl
musicians.attr('src', imageUrl);
musicians.attr('alt', 'musician');
$("#images").push(imageUrl)
//prepend puts the images in the beginning
$("#images").prepend(imageUrl);
$('<img>').val();
console.log(results)
console.log(imageUrl)
//empty gifs button
$('#clearButton').click(function(event){
$(musicians).remove()
});
});
});
};

So it looks like you've got a couple of errors.
First one looks like your usage of the giphy API. If you go to http://api.giphy.com/v1/gifs/search?q=music&api_key=dc6zaTOxFJmzC&limit=10 in your browser, you can see how the data is coming back. The data is returned as an array of GIF objects that each have an "images" property that has an assortment of images you can choose from. Instead of accessing the images like
var imageUrl = response.data.image_original_url;
you need to loop through the response.data array and grab an image, as in the following example
var imageUrl = response.data[i].images.fixed_height.url;
Your other issue is when appending the image element you created to the DOM. You are appending the imageUrl variable (which is just the value of the image URL), instead of the img element you created which is stored in the musicians variable (this will also have to be a part of your loop). In addition, the following:
$("#images").push(imageUrl)
//prepend puts the images in the beginning
$("#images").prepend(imageUrl);
$('<img>').val();
can all be refactored to the single line
$("#images").prepend(musicians);
Your end result should look something like:
for(var i = 0; i < response.data.length; i++){
var imageUrl = response.data[i].images.fixed_height.url;
var musicians = $('<img>');
//takes var musicians and adds attr src and imageUrl
musicians.attr('src', imageUrl);
musicians.attr('alt', 'musician');
//prepend puts the images in the beginning
$("#images").prepend(musicians);
}

Related

Converting Jquery to Vanilla JS stuck on AJAX

I am trying to convert an older jquery script to vanilla JS.
I have been working through most of them just one by one but am having a problem with the ajax call. Can anyone look at my original file and new file and see what is missing?
I am struggling mostly with converting the initial function calls to vanilla js. If you look at the 2nd code drop there most of the 'jquery-isms' have been rewritten in vanilla js. However I am having trouble converting my $.merge and $.extend actions. Furthermore, converting the $.ajax call to a JS version.
I tried to work on it modularly task by task but still haven't gotten it completely polished.
Jquery
(function($){
$(document).ready(function() {
$.ajax({
url: "https://api.flickr.com/services/rest/?method=flickr.galleries.getPhotos&api_key=*PRIVATE*c&gallery_id=72157720949295872&per_page=10&format=json&nojsoncallback=1",
type: "GET",
success: function(data) {
console.log("api successfully called")
let path = data.photos.photo
//for each photo, I save the different individual ids into variables so that they can be easily plugged into a URL
for (let i = 0; i < path.length; i++) {
let obj = path[i];
let farm_id = data.photos.photo[i].farm
let server_id = data.photos.photo[i].server
let photo_id = data.photos.photo[i].id
let secret = data.photos.photo[i].secret
//the static address to photos on Flickr is accessed through this address: https://farm{farm-id}.staticflickr.com/{server-id}/{id}_{secret}.jpg
//this variable is the direct link to access photos on Flickr, minus the ".jpg" designation that will be added, according to whether we are trying to access the medium picture or the large picture
let pic_url = "https://farm" + farm_id + ".staticflickr.com/" + server_id + "/" + photo_id + "_" + secret;
//this is the variable that stores the medium jpeg URL
let pic_url_m = pic_url + "_m.jpg";
//this stores an image tag which will be populated with a medium jpeg URL
let pic_img = ('<img src=\'' + pic_url_m + '\' alt = \"pic\" />');
//this appends the var pic_img to the photo_list div as the function loops through
//$('.body').append('#frame');
$('#photo-list').append(pic_img);
//this appends the class "paginate" to each img tag that is formed, ensuring that the the divs get passed to a later function called customPaginate
// $('img').addClass("paginate")
$('#photo-list img').addClass("paginate");
}
//this passes all divs with the class "pagination" to the function customPaginate
$('.pagination').customPaginate({
itemsToPaginate: ".paginate"
});
//when img tags with the class paginate are clicked, the following function is called
$('.paginate').click(function() {
//this variable saves the "src" or URL of (this) which is any element with the class "paginate"
let src = $(this).attr('src');
//this variable takes the "src" variable, slices the last six characters, and replaces it with "_c.jpg", a large version of the image URL
let src_l = src.slice(0, -6) + "_c.jpg";
//gives the "frame img" element a new attribute, which is the large image URL
$('#frame img').attr('src', src_l);
//allows the the "frame img" element to fade into the screen
$('#frame img').fadeIn();
//allows the "overlay" element to fade onto the screen
$('#overlay').fadeIn();
//when the "overlay" element is clicked, both the "overlay" and "frame img" elements
$('#overlay').click(function() {
$(this).fadeOut();
$('#frame img').fadeOut();
//removes the "src" attribute from "frame img", allowing it to be populated by other image URLs next time an image is clicked
$('#frame img').removeAttr('src');
});
});
}
});
});
//this function generates the customPaginate function, which paginates the images 10 to a page
$.fn.customPaginate = function(options)
{
let paginationContainer = this;
let defaults = {
//sets how many items to a page
itemsPerPage : 10
};
let settings = {};
//merges defaults and options into one one variable, settings
$.extend(settings, defaults, options);
//sets how many items will be on each page
let itemsPerPage = settings.itemsPerPage;
//sets which items are going to be
let itemsToPaginate = $(settings.itemsToPaginate);
//determines how many pages to generate based on the amount of items
let numberOfItems = Math.ceil((itemsToPaginate.length / itemsPerPage));
//this ul will contain the page numbers
$("<ul></ul>").prependTo(paginationContainer);
//loops through the ul tag the same number of times as there are pages. in this case, the loop will run 4 times
for(let index = 0; index < numberOfItems; index++)
{
paginationContainer.find('ul').append('<li>'+ (index+1) + '</li>');
}
//ensures that the current page only displays the items that should be on the specific page, and hides the others
itemsToPaginate.filter(":gt(" + (itemsPerPage - 1) + ")").hide();
//locates the first li element, adds activeClass element to it
paginationContainer.find("ul li").first().addClass(settings.activeClass).end().on('click', function(){
let $this = $(this);
//gives current page the activeClass setting
$this.addClass(settings.activeClass);
//takes activeClass setting away from non-current pages
$this.siblings().removeClass(settings.activeClass);
let pageNumber = $this.text();
//this variable designates that items located on the previous page times the number of items per page should be hidden
let itemsToHide = itemsToPaginate.filter(":lt(" + ((pageNumber-1) * itemsPerPage) + ")");
//this function merges itemsToHide and itemsToPaginate that are greater than the product of the pageNumber and the itemsPerPage minus 1, ensuring that these items are hidden from view
$.merge(itemsToHide, itemsToPaginate.filter(":gt(" + ((pageNumber * itemsPerPage) - 1) + ")"));
//designates these items as items that should be shown on the current page
let itemsToShow = itemsToPaginate.not(itemsToHide);
//hides items from other pages and shows items from current page
$("html,body").animate({scrollTop:"0px"}, function(){
itemsToHide.hide();
itemsToShow.show();
});
});
}
}(jQuery));
Vanilla JS (what im still stuck on)
(function($){
document.querySelector(document).ready(function() {
$.ajax({ //need to convert this to JS
url: "https://api.flickr.com/services/rest/?method=flickr.galleries.getPhotos&api_key=*PRIVATE*c&gallery_id=72157720949295872&per_page=10&format=json&nojsoncallback=1",
type: "GET",
success: function(data) {
console.log("api successfully called")
// ....truncated
}
});
});
$.fn.customPaginate = function()
{
let paginationContainer = this;
let defaults = {
itemsPerPage : 10
};
let settings = {};
//need to convert this extend to JS
$.extend(settings, defaults, options);
let itemsPerPage = settings.itemsPerPage;
// ....truncated
let pageNumber = qS.text();
let itemsToHide = itemsToPaginate.filter(":lt(" + ((pageNumber-1) * itemsPerPage) + ")");
//need to convert this extend to JS
$.merge(itemsToHide, itemsToPaginate.filter(":gt(" + ((pageNumber * itemsPerPage) - 1) + ")"));
});
}
}(jQuery));
First, please see: https://www.w3schools.com/js/js_ajax_intro.asp
Example you might consider.
function getPages(){
const xmlhttp = new XMLHttpRequest();
xmlhttp.onload = function() {
// Everything you want to do with the data
// this.responseText.photos.photo
}
xmlhttp.open("GET", "https://api.flickr.com/services/rest/?method=flickr.galleries.getPhotos&api_key=*PRIVATE*c&gallery_id=72157720949295872&per_page=10&format=json&nojsoncallback=1",);
xmlhttp.send();
}

Deleted images still being shown

For some reason, my website still showing images that were already deleted from the specified folder and I have no idea why that's happening and how to solve that.
Process: When the button to delete all admins is pressed, it calls a PHP function that truncate the tables administration, adminimg and login, delete all images from a folder related to id's on table administration with unlink(), and create a registry on administration table with id=1(auto_increment) and name="abc".
Problem: I have a jQuery function that display a specific admin information on textboxes, verify the value in the textbox for the adminID, and display the image associated to that id. After executing the process above, when i call the jQuery function, it display correctly the id=1 and name="abc" but shows the deleted image associated to the admin with id=1 before truncate the tables.
jQuery function (if necessary)
$(".btneditadmin").click( e =>{
let textvalues = displayDataAdmin(e);
let id = $("input[name*='idadmin']");
let name = $("input[name*='nameadmin']");
id.val(textvalues[0]);
nome.val(textvalues[1]);
var img_url = 'Images/Administration/admin'+$("#idadmin").val()+'.jpg';
$("#admin-image").attr('src',img_url);
});
function displayDataAdmin(e) {
let id = 0;
const td = $("#tbody tr td");
let textvalues = [];
for (const value of td){
if(value.dataset.id == e.target.dataset.id){
textvalues[id++] = value.textContent;
}
}
return textvalues;
}
If you're sure that image isn't there anymore then it's caching issue and something like this would take care of it
let img_url = 'Images/Administration/admin'+$("#idadmin").val()+'.jpg';
img_url += '?' + new Date().getTime() ; // cache killer
$("#admin-image").attr('src', img_url);
However, you're calling that function no matter what so I would suggest a onload/error check
​$('#admin-image').load(function(){ // when loaded successfully
console.log('success');
}).error(function(){ // when theres an error
$(this).remove()
// or you could replace it with a default image
$(this).attr('src', '/images/default.jpg');
});​​​​​

refresh html content with each new GET request

I have been practicing my Vanilla Js/jQuery skills today by throwing together a newsfeed app using the news-api.
I have included a link to a jsfiddle of my code here. However, I have removed my API key.
On first load of the page, when the user clicks on an image for a media outlet, e.g. 'techcrunch', using an addEventListener, I pass the image's id attribute to the API end point 'https://newsapi.org/v1/articles' and run a GET request which then proceeds to create div elements with the news articles content.
However, after clicking 1 image, I cannot get the content to reload unless I reload the whole page manually or with location.reload().
On clicking another image the new GET request is running and returning results, as I am console logging the results.
I am looking for some general guidance on how to get the page content to reload with each new GET request.
Any help would be greatly appreciated.
Many thanks for your time.
Api convention:
e.g https://newsapi.org/v1/articles?source=techcrunch&apiKey=APIKEYHERE
EventListener:
sourceIMG.addEventListener('click', function() {
$.get('https://newsapi.org/v1/articles?source=' + this.id + '&sortBy=latest&apiKey=APIKEYHERE', function(data, status) {
console.log(data);
latestArticles = data.articles;
for (i = 0; i < latestArticles.length; i++) {
//New Article
var newArticle = document.createElement("DIV");
newArticle.id = "article";
newArticle.className += "article";
//Title
//Create an h1 Element
var header = document.createElement("H1");
//Create the text entry for the H1
var title = document.createTextNode(latestArticles[i].title);
//Append the text to the h1 Element
header.appendChild(title);
//Append the h1 element to the Div 'article'
newArticle.appendChild(header);
//Author
var para = document.createElement("P");
var author = document.createTextNode(latestArticles[i].author);
para.appendChild(author);
newArticle.appendChild(para);
//Description
var description = document.createElement("H4");
var desc = document.createTextNode(latestArticles[i].description);
description.appendChild(desc);
newArticle.appendChild(description);
//Image
var image = document.createElement("IMG");
image.src = latestArticles[i].urlToImage;
image.className += "articleImg";
newArticle.appendChild(image);
//Url link
//Create a href element
var a = document.createElement('a');
var link = document.createElement('p');
var innerLink = document.createTextNode('Read the full story ');
link.appendChild(innerLink);
a.setAttribute("href", latestArticles[i].url);
a.innerHTML = "here.";
link.appendChild(a);
newArticle.appendChild(link);
//Append the Div 'article' to the outer div 'articles'
document.getElementById("articles").appendChild(newArticle);
}
});
}, false);
I tried your fiddle using an api key. It is working for me in that content new content is appended to the previous content in the #articles div. If I'm understanding your question, when a news service image is clicked you would like for only that news service's articles to show. To do that you would need to clear the contents of #articles before appending new content.
To do that with plain js you could use the following above your for loop:
// Removing all children from an element
var articlesDiv = document.getElementById("articles");
while (articlesDiv.firstChild) {
articlesDiv.removeChild(articlesDiv.firstChild);
}
for (i = 0; i < latestArticles.length; i++) {...
Full disclosure, I added the variable name 'articlesDiv' but otherwise the above snippet came from https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild

How to display image from another page in my page

I want to start a greasemonkey plugin to an existing page. The plugin should fetch and display some images automatically, each image from different pages.
I thought of using jQuery.get("link", function(data)) and hide the page and display the images only but on an average to display 4 images I should load 6 webpages into present webpage it is creating a delay in loading.
Is there any other work around to create a function that loads the page html of all image pages in background or in another tab and get the href of <a> tag's in that page, into my page and load only images into my page?
You can try this solution below.
Just put the URLs you want in the "pages" array. When the script runs, it makes Ajax calls in the background. When they are ready, it searches the source returned for images and picks one randomly. If found, it wraps the image in a link to the page where it found it (or if available, the image's url) and inserts the linked image to the top of the body of your own current page.
You can try the code by pasting it into your browser's JavaScript console and it will add the images to the current page.
You also see a demo here: http://jsfiddle.net/3Lcj3918/3/
//pages you want
var pages =
[
'https://en.wikipedia.org/wiki/Special:Random',
'https://en.wikipedia.org/wiki/Special:Random',
'https://en.wikipedia.org/wiki/Special:Random',
'https://en.wikipedia.org/wiki/Special:Random',
'https://en.wikipedia.org/wiki/Special:Random'
]
//a simple function used to make an ajax call and run a callback with the target page source as an argument when successful
function getSubPageSource(url, successCallback)
{
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4 && xhr.status == 200)
{
//when source returned, run callback with the response text
successCallback(xhr.responseText);
}
};
//requires a proxy url for CORS
var proxyURL = 'https://cors-anywhere.herokuapp.com/';
xhr.open('GET', proxyURL+url, true);
//set headers required by proxy
xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
xhr.setRequestHeader("Access-Control-Allow-Origin","https://cors-anywhere.herokuapp.com/");
xhr.send();
}
//a function that extract images from given url and inserts into current page
function injectImagesFrom(url)
{
getSubPageSource(url, function(data)
{
//trim source code to body only
var bodySource = data.substr(data.indexOf('<body ')); //find body tag
bodySource = bodySource.substr(bodySource.indexOf('>') + 1); //finish removing body open tag
bodySource = bodySource.substring(0, bodySource.indexOf('</body')); //remove body close tag
//create an element to insert external source
var workingNode = document.createElement("span");
//insert source
workingNode.innerHTML = bodySource;
//find all images
var allImages = workingNode.getElementsByTagName('img');
//any images?
if (allImages.length > 0)
{
//grab random image
var randomIndex = Math.floor(Math.random() * allImages.length);
var randomImage = allImages.item(randomIndex);
//add border
randomImage.setAttribute('style', 'border: 1px solid red;');
//restrain size
randomImage.setAttribute('width', 200);
randomImage.setAttribute('height', 200);
//check if parent node is a link
var parentNode = randomImage.parentNode;
if (parentNode.tagName == 'A')
{
//yes, use it
var imageURL = parentNode.getAttribute('href');
}
else
{
//no, use image's page's url
var imageURL = url;
}
//add a link pointing to where image was taken from
var aLink = document.createElement("a");
aLink.setAttribute('href', imageURL);
aLink.setAttribute('target', '_blank');
//insert image into link
aLink.appendChild(randomImage);
/* INSERT INTO PAGE */
//insert image in beginning of body
document.body.insertBefore(aLink,document.body.childNodes[0]);
//remove working node children
while (workingNode.firstChild) {
workingNode.removeChild(workingNode.firstChild);
}
//unreference
workingNode = null;
}
});
}
for (var ii = 0, nn = pages.length; ii < nn; ii++)
{
injectImagesFrom(pages[ii]);
}

Javascript: Get the innerHTML of a dynamically created div

I am retrieving some information from an xml file ( movie information ) and I am creating dynamically some DOM elements according to each movie. I want, when I click on the test element, to get the value of the title of the movie. Right now, no matter which movie I click, it gets the title of the last movie that was introduced.
How can I get the title of each individual movie when I click on that div and not the last one introduced by the for-loop?
xmlDoc=xmlhttp.responseXML;
var x=xmlDoc.getElementsByTagName("movie");
for (i=0;i<x.length;i++)
{
var titlu = x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue;
var description = x[i].getElementsByTagName("description")[0].childNodes[0].nodeValue;
var descriere = document.createElement('div');
descriere.className='expandedDescriere';
descriere.innerHTML = description;
var titlediv = document.createElement('div');
titlediv.className = 'title';
titlediv.id='title';
titlediv.innerHTML = title;
var test=document.createElement('div');
test.className='test';
test.onclick= function(){
var filmName= test.previousSibling.innerHTML;
alert(filmName);
}
placeholder.appendChild(titlediv);
placeholder.appendChild(test);
placeholder.appendChild(descriere);
}
I think your problem might be in the function you assigned to onclick:
test.onclick= function(){
var filmName= test.previousSibling.innerHTML; // <===
alert(filmName);
}
the marked line should be var filmName= this.previousSibling.innerHTML;
My guess is that the var test is hoisted out of the for loop, meaning that when the loop finished, all the onclick function are referencing the same test variable which is the last element you created.
Use this to reference the clicked element:
test.onclick = function() {
var filmName = this.previousSibling.innerHTML;
alert(filmName);
};

Categories

Resources