Getting access to the index in plain JS - javascript

so I'm building a seemingly simple playlist JS app with a rails backend and I'm running into an issue. I cannot seem to get the return value I want. I have my tracks and playlist rendered but I need to get the index of each song on the page and I am only able to figure out how to get the first track. I'm new to JS as you can probably tell so any advise you have would be great. Thanks in advance.
function getPlaylists() {
fetch(BACKEND_URL)
.then(response => response.json())
.then(list => {
list.data.map((playlist, index) => {
let newPlaylist = new Playlist(playlist, playlist.attributes) ;
document.getElementById('playlist-container').innerHTML += newPlaylist.renderPlaylistCard();
})
}
)
}
function postFetch(title, artist){
fetch(BACKEND_URL, {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({
name: name,
title: title,
artist: artist
})
})
.then(response => response.json())
.then(playlist => {
const playlistData = playlist.data;
let newPlaylist = new Playlist(playlistData, playlistData.attributes);
document.getElementById('playlist-container').innerHTML += newPlaylist.renderPlaylistCard() ;
})
}
```class Playlist {
constructor(playlist, playlistAttributes) {
this.id = playlist.id
this.name = playlistAttributes.name
this.track = playlistAttributes.tracks
Playlist.all.push(this);
//debugger
}
renderPlaylistCard() {
return `
<div data-id=${this.id}>
<h3><li>Playlist Name: ${this.name}</h3></li>
<h3><li>Title: ${this.track[0].title}</h3></li>
<h3><li>Title: ${this.track[0].artist}</h3></li>
<button data-id=${this.id}>EDIT!</button>
</div> </li>
` ;
}
}
Playlist.all = [];

Related

How to make API calls in Vanilla JS

Am building a weather app using vanilla JS and weatherbit rapid API, but whenever I run the program, it logs an error Can not read properties of undefined (reading 'temp')
const tempValue = document.getElementsByClassName('temp')
// console.log(cityName)
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Key': '************************************',
'X-RapidAPI-Host': 'weatherbit-v1-mashape.p.rapidapi.com'
}
}
document.getElementById('submit').addEventListener('click', e => {
e.preventDefault()
fetch(
'https://weatherbit-v1-mashape.p.rapidapi.com/forecast/3hourly?lat=35.5&lon=-78.5',
options
)
.then(response => response.json())
.then(data => {
let tempval = data['temp']
tempValue.innerHtml = tempval
})
.catch(err => console.error(err))
})
pls consult the docs.
https://rapidapi.com/weatherbit/api/weather
response object structure is:
{
country_code:"US",
lon:-78.5,
data: [...],
city_name:"Four Oaks",
lat:35.5,
timezone:"America/New_York",
state_code:"NC",
}
To access 'temp'. use `
fetch(
'https://weatherbit-v1-mashape.p.rapidapi.com/forecast/3hourly?lat=35.5&lon=-78.5',
options
).then(response => {
const someItemIndex = 0;
console.log(response.data);
const tempval = response.data[someItemIndex].temp
tempValue.innerHtml = tempval
})
.catch(err => console.error(err))
there is no temp in response. and there is no any field 'temp' in data. Temp is defined only on iterable items of data array.
After some advice I received from this platform, I have managed to modify the code and it's working perfectly. The problem was in the way I was accessing the fields from the JSON. I am new to APIs and this is an excellent start for me thank you.
Modified Code
const tempValue = document.querySelector('.temp')
const cityName = document.querySelector('.city_name')
const humid = document.querySelector('.humidity')
const weatherValue = document.querySelector('.weather')
// console.log(cityName)
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Key': '30583b6ad4msh649637ae1b0f6d3p1edde0jsn53b7839146a2',
'X-RapidAPI-Host': 'weatherbit-v1-mashape.p.rapidapi.com'
}
}
document.getElementById('submit').addEventListener('click', e => {
e.preventDefault()
fetch(
'https://weatherbit-v1-mashape.p.rapidapi.com/forecast/3hourly?lat=35.5&lon=-78.5',
options
)
//Modified code
.then(response => response.json())
.then(response => {
const someItemIndex = 0
console.log(response.data)
const tempval = response.data[someItemIndex].temp
const cityval = response.city_name
const weatherval = response.data[someItemIndex].weather.description
// console.log(tempval)
tempValue.innerHTML = `<h3>Temperature: </h3>${tempval}&#x2103`
weatherValue.innerHTML = `<h3>Weather Description: </h3>${weatherval}`
cityName.innerHTML = `<h3>City Name: </h3>${cityval}`
})
.catch(err => console.error(err))
})

MongoDB server Value cannot update?

I am making a simple website.. i use react, MongoDB, JavaScript. My Problem is when click delivered button the quantity increase i update my UI and MongoDB Server. When Code is run in MongoDB server quantity is null..
Here is the code
const handleDelivered = data => {
const { quantity, ...rest } = bookItem;
const quantity1 = parseInt(bookItem.quantity) - 1;
const quantityStr = quantity1.toString();
const newQuantity = { quantity: quantityStr, ...rest }
setBookItem(newQuantity);
const getquantity = bookItem.quantity;
console.log(getquantity);
const updateQuantity = { getquantity };
const url = `http://localhost:5000/items/${itemsId}`;
fetch(url, {
method: 'PUT',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(updateQuantity)
})
.then(res => res.json())
.then(data => {
console.log(data);
})
}

this.funtionName is not defined [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 1 year ago.
I am learing to use API an making a news website where you can search a term. I am using the code given below to do so.
var newsAccordion = document.getElementById("newsAccordion");
let news = {
apiKey: "xxxxxxxxxx",
fetchNews: function () {
fetch(
"https://gnews.io/api/v4/top-headlines?&country=in&lang=en&token=xxxxxxxxxxx"
)
.then((response) => response.json())
.then((data) => {
this.fetchCotent(data);
});
},
fetchCotent: (data) => {
console.log(data);
size = data.articles.length;
let newsHtml = "";
for (var i = 0; i < size; i++) {
const { title } = data.articles[i];
const { publishedAt } = data.articles[i];
const { url } = data.articles[i];
const { image } = data.articles[i];
const { description } = data.articles[i];
console.log(title, publishedAt);
var date = new Date(publishedAt).toLocaleString(undefined, {
timeZone: "Asia/Kolkata",
});
}
newsAccordion.innerHTML = newsHtml;
},
searchNews: (term) => {
console.log(term);
fetch(
"https://gnews.io/api/v4/search?&lang=en&q=" +
term +
"&token=xxxxxxxxxx"
)
.then((response) => response.json())
.then((data) => {
this.serchNews();
});
},
searchNews: (term) => {
//code goes here
};
document
.querySelector(".search button")
.addEventListener("click", function (e) {
e.preventDefault();
news.searchNews(document.querySelector(".search-bar").value);
});
window.onload = function () {
news.fetchNews();
};
But the problem is its gaving an error sying
Uncaught (in promise) ReferenceError: showSearch is not defined
at index.js:59
At index.js:59 it says:
Uncaught (in promise) TypeError: this.showSearch is not a function
My question is why is this happening and how can I solve it?
Thanks for any help in advance.
Replace arrow function to regular function for searchNews and showSearch. So that it gets the current scope using this, because arrow function doesn't have it's own context; it takes the context of enclosing function.
searchNews: function(term) {
console.log(term);
fetch(
"https://gnews.io/api/v4/search?&lang=en&q=" +
term +
"&token=368ddd2e4d1c1c559f1fb904cb1e09fa"
)
.then((response) => response.json())
.then((data) => {
this.showSearch(data);
});
},
showSearch: function(data) {
size = data.articles.length;
// your code...
},
Working code example:
const news = {
searchNews: function (term) {
console.log("search news: ", term);
fetchApi("https://gnews.io/api/v4/search")
.then((response) => response.json())
.then((data) => {
console.log("received data:");
this.showSearch(data);
});
},
showSearch: function (data) {
console.log("showSearch: ", data);
// your code...
}
}
function fetchApi(url) { // fetch api stub
return new Promise((resolve, reject) => {
const response = {
data: { id: 123, title: "test-title" },
statusCode: 200
}
let responseObj = new Response(JSON.stringify(response))
setTimeout(resolve(responseObj), 500);
})
}
document.querySelector("#search-button").addEventListener("click", function (e) {
e.preventDefault();
news.searchNews(document.querySelector("#search-bar").value);
});
<html>
<head></head>
<body>
<div>Enter search title:
<input type="text" id="search-bar">
</div>
<div style="margin-top: 20px">
<button id="search-button">Search News</button>
</div>
</body>
</html>
This is because of the misunderstanding of this in Javascript. Please read the this in Javascript.
Anyway you can modify the code as follows.
const obj = {
searchNews: (term) => {
console.log(term);
function cbFunc(data) {
this.showSearch(data);
}
fetch(
"https://gnews.io/api/v4/search?&lang=en&q=" +
term +
"&token=368ddd2e4d1c1c559f1fb904cb1e09fa"
)
.then((response) => response.json())
.then(cbFunc.bind(obj));
},
showSearch: (data) => {
size = data.articles.length;
let newsHtml = "";
for (var i = 0; i < size; i++) {
const { title } = data.articles[i];
const { publishedAt } = data.articles[i];
const { url } = data.articles[i];
const { image } = data.articles[i];
const { description } = data.articles[i];
var date = new Date(publishedAt).toLocaleString(undefined, {
timeZone: "Asia/Kolkata",
});
console.log(title, date, url, image, description);
}
}
}
Please place emphasis on bind call, where obj should be your wrapper object(at the top line of the code).

Try download img from firebase storage which link is firebase database

I tried to download the image which is in firebase storage which link is store in database. When I tried to download the image, it takes more time to execute while for loop is completed.
Is there any process that somehow I download in time which doesn't make the function really slow? I already solve this issue using setTimeout but I hope there may be a better solution than mine. Help me! thank you!
export const shampooHandler = () => {
return (dispatch) => {
dispatch(shampooStart());
const data = [];
const imgList = [];
fire
.database()
.ref()
.child("Shampoo")
.once("value")
.then((response) => {
for (let i = 0; i < response.val().length; i++) {
fire.storage().refFromURL(response.val()[i].img).getDownloadURL().then((image) => {
imgList.push(image);
})
.catch((error) => {
dispatch(shampooError(error));
});
setTimeout(() => {
name = response.val()[i].name;
description = response.val()[i].description;
value = response.val()[i].value;
img = imgList[i];
data.push({ name, description, value, img });
if (i === (response.val().length - 1)) {
dispatch(shampooSuccess(data));
}
}, 3000);
}
})
.catch((error) => {
dispatch(shampooError(error));
});
};
};
I spend a day finding a right solution for it. It may help someone to find solution in future. Thanks guys for giving a thought and specially DougStevensen to tiggering me an idea
export const shampooHandler = () => {
return (dispatch) => {
dispatch(shampooStart());
const data = [];
const imglist = [];
fire.database().ref().child("Shampoo").once("value").then((response) => {
response.val().forEach(element => {
const promise = imageUrlHandler(element.img).then(url => {
return url;
}).catch(error =>{
dispatch(shampooError(error));
})
imglist.push(promise);
//all the promise call to download the images
Promise.all(imglist).then(items =>{
const dataCollection = {
name: element.name,
description: element.description,
value: element.value,
img: items[items.length - 1]
}
data.push(dataCollection);
if(data.length === response.val().length){
dispatch(shampooSuccess(data));
}
}).catch(err =>dispatch(shampooError(err)));
})
}).catch(error => {
dispatch(shampooError(error));
})
}
}
export const imageUrlHandler = (databaseUrl) => {
return new Promise((resolve,reject)=> {
fire.storage().refFromURL(databaseUrl).getDownloadURL().then((url) => {
resolve(url);
})
.catch((error) => {
reject(error)
});
})
}

Get images from JSON response

I am developing a shopify theme. Inside my theme. I have a div that I am looping. Inside the div, I have an image tag where I want to pass in the image from my JSON file
where the div id == to the image id
In my HTML file, I have this.
{% for order in customer.orders %}
{% for line_item in order.line_items %}
<span id="lineNumber">{{ line_item.product_id }}</span>
<div class="order-body">
<div class="row order-single">
<div class="col-12 col-md-3">
<img src="" alt="logo" class="fit-image-product" id="imglink">
</div>
...
{% endfor %}
{% else %}
<div class="container">
<div class="lg-header">
<h3>You are not Logged In</h3>
</div>
</div>
{% endif %}
In my script file, I have this
const lineNumberElements = document.querySelectorAll("#lineNumber");
let arrayOfLineNumbers = [];
for (const key in lineNumberElements) {
if (lineNumberElements.hasOwnProperty(key)) {
const element = lineNumberElements[key];
arrayOfLineNumbers.push(element.innerHTML);
}
console.log(arrayOfLineNumbers[key]);
}
const imgsrcElements = document.querySelectorAll("#imglink");
let arrayOfimgSrc = [];
for (const key in imgsrcElements) {
if (imgsrcElements.hasOwnProperty(key)) {
const element = imgsrcElements[key];
arrayOfimgSrc.push(element.innerHTML);
}
console.log(arrayOfimgSrc[key]);
}
const geturl = `https://website.myshopify.com//admin/api/2020-04/products.json`;
fetch(geturl, {
method: "GET",
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": "shppa_###################",
},
})
.then((response) => {
// console.log('resolved', response);
return response.json();
})
.then((data) => {
let allproducts = data.products;
console.log(allproducts);
allproducts.forEach(function (product) {
let product_id = product.id;
let product_image = product.image.src;
//console.log(product_id);
if (product_id == arrayOfLineNumbers[key]) {
console.log("how far", product_id, product_image);
arrayOfimgSrc[key] = product_image;
}
});
})
.catch((error) => {
console.error("There has been a problem with your operation:", error);
});
I kept getting the error
There has been a problem with your operation: ReferenceError: key is not defined
UPDATE
I have been able to minimize my code and error has been removed, but the first image was sent and looped over.
const lineNumberElements = document.querySelectorAll('#lineNumber');
const imgsrcElements = document.querySelectorAll('#imglink');
const geturl = `https://beymossweb.myshopify.com//admin/api/2020-04/products.json`
fetch(geturl, {
method: "GET",
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": "shppa_#############",
}
})
.then((response) => {
return response.json();
})
.then(data => {
let allproducts = data.products
console.log(allproducts)
allproducts.forEach(function (product) {
let product_id = product.id
let product_image = product.image.src
console.log(product_id, product_image);
for (let j = 0; j <= imgsrcElements.length; j++) {
imgsrcElements[j].src = product_image;
}
});
})
.catch(error => {
console.error('There has been a problem with your operation:', error);
});
In order to collaborate, it is not a solution to the case you describe but I think it can put us on track to solve it
The methods commented as helpers obtain the text of each lineNumber and the value of src of each imglink, manipulating them as an array, thus solving what I commented regarding for-in
Within the successful fetch response I am not clear what you are trying, I understand that in this line product_id == arrayOfLineNumbers [key] what you want is to check if there is a value equal to arrayOfLineNumbers in the array if that is the case this line will achieve your goal arrayOfLineNumbers.includes(product_id)
Finally in this line arrayOfimgSrc[key] = product_image; your intention is not clear
key does not exist in this context
the line tries to assign product_image to an array if it is the case you must use push method
As I mentioned at the beginning this is not intended to be a solution but perhaps by correcting some things and commenting on doubts we can reach the solution
// helpers
const toTextContent = (element) => element.textContent;
const toSrc = (element) => element.src;
const nodesToArray = (nodes) => Array.from(nodes);
const getTextContent = (nodes) => nodesToArray(nodes).map(toTextContent);
const getSrc = (nodes) => nodesToArray(nodes).map(toSrc);
// collections
const arrayOfLineNumbers = getTextContent(
document.querySelectorAll("#lineNumber")
);
const arrayOfimgSrc = getSrc(document.querySelectorAll("#imglink"));
// ajax
const geturl = `https://website.myshopify.com//admin/api/2020-04/products.json`;
fetch(geturl, {
method: "GET",
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": "shppa_###################",
},
})
.then((response) => response.json())
.then((data) => {
data.products.forEach((product) => {
let product_id = product.id;
let product_image = product.image.src;
if (arrayOfLineNumbers.includes(product_id)) {
console.log("how far", product_id, product_image);
arrayOfimgSrc[key] = product_image;
}
});
})
.catch((error) => {
console.error("There has been a problem with your operation:", error);
});

Categories