So I'm trying to use vanilla JavaScript and do a fetch from iTunes' API to create a page that allows a user to type in an artist name and then compile a page with like 15 top results. I'm using the following for my fetch:
function dataPull() {
fetch("https://itunes.apple.com/search?term=")
.then(function(response) {
if (response.status !== 200) {
console.log(response.status);
return;
}
response.json().then(function(data){
console.log(data);
let returnResponse = document.createElement("div");
let input2 = inputElement.value;
for (let i=0; i<data.length; i++){
if (inputElement===data[i].artistName){
console.log(data[i].artistName);
returnResponse.innerHTML = `
<div class="box">
<img src=${artWorkUrl30} alt="Album Image">
<p><span>Artist Name:</span>${data[i].artistName}</p>
<p><span>Track: </span>${data[i].trackName}</p>
<p><span>Album Name: </span>${data[i].collectionName}</p>
<p><span>Album Price: </span>${data[i].collectionPrice</p>
</div>
`;
results.appendChild(returnResponse);
}}
console.log(data);
});
}
)
The function is being called in a click event and I'm sure I can put everything from "let returnResponse" down to the append in another function. The issue I'm having is actually getting the API to show ANY results. At the moment if I type in Bruno Mars, Beethoven, or U2 it's not logging any data and it's giving me "Provisional Headers are Shown" when I check out the the Status Code.
Any thoughts on what I could do to make this better/work?
For full code:
jsfiddle
Typical fetch call will look like this.
fetch(`${url}`)
.then(response => response.json())
.then(json =>
// do something with the json
)
Modify your code and see if you can console.log() anything of note.
I would reccomend seperating your concerns. Making the dataPull function just get the results. That means you can use this code at other places without changing it.
Here the function returns the json object as a promise.
function dataPull(search) {
return fetch("https://itunes.apple.com/search?term="+search).then(res => res.json());
}
No you can call the dataPull function and resolve the promise. You'll have the result and can do what you want with it.
dataPull("test").then(res => {
console.log(res.results);
/*
res.results.forEach(item => {
div and span magic here
})
*/
})
Here's a link to a working JSFiddle.
https://jsfiddle.net/14w36u4n/
Related
I am trying to understand this Promise/fetch thing in js.
'use strict'
const list = document.querySelector('.list');
function test() {
return fetch('https://swapi.dev/api/films/', {
method: 'GET'
});
}
list.addEventListener('click', event => {
console.log('TEST');
alert("TEST");
});
test()
.then( function(response) {
return response.json();
})
.then(function(data) {
data.results.forEach(function(episode) {
const ul = document.createElement('ul');
ul.innerHTML = episode.title;
list.append(ul);
})
})
.list {
cursor: pointer;
}
<ul class="list"></ul>
I need to from a drop-down list, from all the STAR WARS episodes(done), and more of that (the part where the troubles start) by click on the episode it must return a list of ships, used in the episode.
As you can see from the link code above - I was able to return the list of episodes correctly, but I just don't know how to create the drop-down menu currently I'm out of ideas, should I make a ul-li list, where ul - episodes and ul - ships?
Kinda hard for me to figure this one out, please Obi-van, you are my last hope.
Firstly what you've done is not a dropdown but a regular list. Use <select> tag.
<select id="episodes" class="list"></select>
Then just add another element into the markup:
<select id="ships" class="list"></select>
Then go to your api documentation and check what it can offer. Firstly let's see what you receive from your endpoint /films/: https://swapi.dev/documentation#films
Obviously here you can find titles of each episode. Done by you. But you can also notice that the response has a list of links to starships endpoint. That's what you need for your second list.
Getting ships:
There're plenty of ways but let's take the easiest one. Luckily your api offers you a way to search an episode by title (https://swapi.dev/documentation#search).
let's build request url:
const nameOfEpisode = event.target.value;
const requestUrl = "https://swapi.dev/api/films/?search=${nameOfEpisode}";
Now we need a click handler. But before implementing it let's to refactor your test() function by giving it a proper name and making it more general so you could reuse it for both requests:
function apiGetRequest(url) {
return fetch(url, method: 'GET').then(response => response.json())
}
Now click handler:
function requestShips(event) {
const nameOfEpisode = event.target.value;
const requestUrl = `https://swapi.dev/api/films/?search=${nameOfEpisode}`;
apiGetRequest(requestUrl).then(data => {
const { starshipsUrls } = data[0];
return starshipsUrls;
}).then(requestStartshipNames)
.then(renderStartshipList);
}
Implementing requestStartshipNames will involve several requests (one request per each starshipUrl). To get all the data synchronously let's use Promise.all:
function requestStartshipNames(starshipUrls){
return Promise.all(starshipUrls.map(url => apiGetRequest(url)));
}
Now to render the starships list you'll need to implement renderStartshipList function:
function renderStartshipList(starships){
const startShipsList = document.querySelector('#ships');
const starcheepsNames = starships.map(({ name }) => {
const option = document.createElement('option');
option.innerHTML = name;
startShipsList.append(option);
})
}
Of course you'll need to refactor your own code in order to match it with the new apiGetRequest utility function, new click handler and the new markup.
Good luck!
I cannot find a question that does anything remotely similar.
I know how to build a text box in React or HTML, but I'm not sure how to parse the inputs as a URL, returning a display of said content.
Basically I need:
- A text box which takes a URL as an input
- Return said contents of URL
- Store text in URL in an array
There are a few other things to do, but those have been my biggest holdups.
This is a textbox in HTML:
https://github.com/mdn/learning-area/blob/master/html/forms/your-first-HTML-form/first-form-styled.html
This is a textbox in React:
https://codepen.io/gaearon/pen/VmmPgp?editors=0010
I've successfully set up both to take inputs, but not sure how to display contents of said input. I know there's something called an Ajax request? But the documentation was hard to follow.
input = url
display(url)
newList = list(text(url))
If I understood this correctly then this is what you want,
<textarea ref="searchURL" placeholder="Enter URL..." onChange={this.getData}/>
getData(){
let url = this.refs.searchFeed.value;
this.refs.searchFeed.value = '';
fetch(url)
.then(response => {
return response.json();
})
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log("error", error)
reject(error);
});
}
I am learning how to use fetch APIs and I can't seem to figure out why only 1 image is showing up when using the Unsplash API. I think it has something to do with map, but I'm not sure. Any help our guidance is appreciated.
document.getElementById("search").addEventListener("click", () => {
const searchTerm = document.getElementById("searchBox").value;
console.log(searchTerm);
fetch(
`https://api.unsplash.com/search/photos?client_id=e72d3972ba3ff93da57a4c0be4f0b7323346c136b73794e2a01226216076655b&query=${searchTerm}`
)
.then(response => response.json())
.then(data => {
console.log(data);
console.log(data.results);
let searchResults = data.results
.map(searchResults => {
return (document.getElementById("app").innerHTML = `<img src="${
searchResults.urls.small
}">`);
})
.join("");
});
});
Code Sandbox here: https://codesandbox.io/s/yq918mok29
The default 10 images should appear but only 1 shows up. How can I map through the images and show them on the page?
You're overwriting the element's content in each map iteration, so you only see the last one. Use map to build the markup, then drop it into the document.
Something like this:
.then(data => {
let imagesMarkup = '';
data.results
.map(searchResults => {
return (imagesMarkup += `<img src="${searchResults.urls.small}">`);
}); // note that the join was removed here
document.getElementById("app").innerHTML = imagesMarkup;
});
Demo
Pretty novice to Javascript. So any help would be great.
I'm using the fetch to retrieve html from a search like below:
var downloadHtml;
fetch(
'https://cors-
anywhere.herokuapp.com/https://www.youtube.com/results?
search_query=A+Song'
)
.then(r => r.text())
.then(data => (downloadHTML = data))
Is it then possible to call another function or perform matches on the downloaded content. So in the method below if you was to execute this on the basepage of the Url in question it would return the list on all the video tags in question.
let GetSongLinks = () => {
var songs = []
let count = document.querySelectorAll('a#video-title.yt-
simple-endpoint.style-scope.ytd-video-renderer').length;
const baseUrl = 'https://www.youtube.com/watch?v='
for (var i = 0; i < count; i++) {
let baseSong = document.querySelectorAll
('a#video-title.yt-simple-endpoint.style-scope.ytd-video-
renderer')[i].innerText
let songId = document.querySelectorAll
('a#video-title.yt-simple-endpoint.style-scope.ytd-video-
renderer'
)[i].data.watchEndpoint.videoId
console.log(songs.push( baseSong + ' - ' + baseUrl + songId))
}
}
Is it possible to either call this function after the promise has been returned and pass data to the function to query these? Or is there a way to scrape the downloadHtml into the variable to find these values? Or even if this is possible? or not? Any suggestions would be appreciated.
As I understand it you can definitely invoke a cleaning method like that inside .then(). It comes down to style. Have the method take in data, and invoke it in your second .then().
There could be ways to scrape your data. It's hard without seeing the data. Consider posting a snippet of the data you get back.
The following code retrieves comments from a comment section of a youtube video. The thing is it retrieves 20 comments and if there is more it retrieves a next token. I am not very experienced using promises so I wonder how can I get all comments in the section until there is no token anymore?
This code is the example code from a npm package called youtube-comment-api
I guess my question is very easy to solve, but right now I have no clue.
Example:
const fetchCommentPage = require('youtube-comment-api')
const videoId = 'DLzxrzFCyOs'
fetchCommentPage(videoId)
.then(commentPage => {
console.log(commentPage.comments)
return fetchCommentPage(videoId, commentPage.nextPageToken)
})
.then(commentPage => {
console.log(commentPage.comments)
})
You should use recursion in order to get comments from all pages. Something like this should work:
// returns a list with all comments
function fetchAllComments(videoId, nextPageToken) {
// nextPageToken can be undefined for the first iteration
return fetchCommentPage(videoId, nextPageToken)
.then(commentPage => {
if (!commentPage.nextPageToken) {
return commentPage.comments;
}
return fetchAllComments(videoId, commentPage.nextPageToken).then(comments => {
return commentPage.comments.concat(comments);
});
});
}