API_Multiple users - javascript

**I need to make a table with 6 random users using html. I only get one user data !
what should i do ? do i have to make a loop ?
this is the code i useed **
i tried to change the id but there was no output.
please let me know what approach i shall follow.
`
<body>
<h2>API</h2>
<table>
<thead>
<th>Full Name</th>
<th>Age</th>
<th>Gender</th>
<th>Location</th>
<th>Country</th>
</thead>
<tbody>
<tr>
<td id="fullname"></td>
<td id="age"></td>
<td id="gender"></td>
<td id="location"></td>
<td id="counrty"></td>
</tr>
<tr>
<td id="fullname"></td>
<td id="age"></td>
<td id="gender"></td>
<td id="location"></td>
<td id="counrty"></td>
</tr>
</table>
<script>
const api_url="https://randomuser.me/api/";
async function getUser() {
const response= await fetch(api_url);
const data= await response.json();
const user=data.results[0];
let{first, last} = user.name;
let{gender, email, phone} = user;
let age = user.dob.age;
let{city, state, country} = user.location;
let fullName = first + " " + last;
document.querySelector("#fullname").textContent = fullName;
document.querySelector("#age").textContent = age;
document.querySelector("#gender").textContent = gender;
document.querySelector("#location").textContent = city + " ," + state;
document.querySelector("#counrty").textContent= country;
}
getUser();
</script>
</body>
</html>
`
what shall i do to take more random users ?
shall i create more ids?

I advise you when using any other people's code (api/framework etc.) to go and look at the documentation.
As you can see from my code below, you can specify how many users you want as return from the api and do a simple forEach to insert them into the table.
const userNumber = 6;
const api_url = "https://randomuser.me/api/?results=" + userNumber; //change number base to your need.
async function getUser() {
const response = await fetch(api_url);
const data = await response.json();
data.results.forEach(user => {
let {
first,
last
} = user.name;
let {
gender,
email,
phone
} = user;
let age = user.dob.age;
let {
city,
state,
country
} = user.location;
let fullName = first + " " + last;
document.querySelector('tbody').innerHTML +=
`<tr>
<td data-fullname>${fullName}</td>
<td data-age>${age}</td>
<td data-gender>${gender}</td>
<td data-location>${city} , ${state}</td>
<td data-country>${country}</td>
</tr>`;
});
}
getUser();
<h2>API</h2>
<table border="1">
<thead>
<th>Full Name</th>
<th>Age</th>
<th>Gender</th>
<th>Location</th>
<th>Country</th>
</thead>
<tbody></tbody>
</table>
Remember instead that the ID of the elements must be unique

Related

How to search/find a words/data (in this case "Country ") from a table ( api data) with a search box?

I want to search country names with that text box, find the specific data from that massive list of names, and show that the only data to the user, not all the data. Please help me to do that. I have no idea how to do this.
// api section
const tbody = document.querySelector('#tbody');
const getdata = async () => {
const endpoint = "https://api.covid19api.com/summary",
response = await fetch(endpoint),
data = await response.json(),
Countries = data.Countries;
Countries.forEach(countryObj => {
let { Country, NewConfirmed, TotalConfirmed, NewDeaths, TotalDeaths, NewRecovered, TotalRecovered, Date } = countryObj;
tbody.innerHTML += `<tr>
<td>${Country}</td>
<td>${NewConfirmed}</td>
<td>${TotalConfirmed}</td>
<td>${NewDeaths}</td>
<td>${TotalDeaths}</td>
<td>${NewRecovered}</td>
<td>${TotalRecovered}</td>
<td>${Date}</td>
</tr>`;
});
}
getdata();
<---------------------------- search box function------------->
// Don't know how to do it.....help me ....Thanks in advance :)
<!--------------search Box & search button ------- -->
<input type="text" id="myInput" placeholder=" Search Country " >
<input type="submit" value="Search" class="submit">
<!----------------data table--------------- -->
<table class="table">
<thead>
<tr>
<th scope="col">Country</th>
<th scope="col">NewConfirmed</th>
<th scope="col">TotalConfirmed</th>
<th scope="col">NewDeaths</th>
<th scope="col">TotalDeaths</th>
<th scope="col">NewRecovered</th>
<th scope="col">TotalRecovered</th>
<th scope="col">Last Updated on</th>
</tr>
</thead>
<tbody id="tbody">
</tbody>
</table>
I want to search country names with that text box, find the specific data from that massive list of names, and show that the only data to the user, not all the data. Please help me to do that.
The only thing that is actually needed here is a way to 'search' the data and display those results. This can be done using the filter() method for an array.
Essentially, you just need to store your data in a global variable that can be filtered later, based on user input. Also, I usually make it a point to separate certain functionality, like displaying data. So instead of displaying the country data inside of the getData() function, I would create a separate function that just filters and displays data. This way you can call it after you fetch the data, and then call that same function each time you search (rather than have repeated code that displays countries in the table).
let countriesData = [];
const getdata = async () => {
const endpoint = "https://api.covid19api.com/summary",
response = await fetch(endpoint),
data = await response.json();
countriesData = data.Countries;
_DisplayCountries();
}
const _DisplayCountries = (c = "") => {
let tbody = document.querySelector("#tbody");
tbody.innerHTML = ``;
countriesData.filter(country => country.Country.toLowerCase().includes(c.toLowerCase())).forEach(result => {
tbody.innerHTML += `<tr>
<td>${result.Country}</td>
<td>${result.NewConfirmed}</td>
<td>${result.TotalConfirmed}</td>
<td>${result.NewDeaths}</td>
<td>${result.TotalDeaths}</td>
<td>${result.NewRecovered}</td>
<td>${result.TotalRecovered}</td>
<td>${result.Date}</td>
</tr>`;
});
}
getdata();
document.querySelector("#mySubmit").addEventListener("click", e => {
_DisplayCountries(document.querySelector("#myInput").value);
});
<input type="text" id="myInput" placeholder=" Search Country ">
<input type="submit" id="mySubmit" value="Search" class="submit">
<table class="table">
<thead>
<tr>
<th scope="col">Country</th>
<th scope="col">NewConfirmed</th>
<th scope="col">TotalConfirmed</th>
<th scope="col">NewDeaths</th>
<th scope="col">TotalDeaths</th>
<th scope="col">NewRecovered</th>
<th scope="col">TotalRecovered</th>
<th scope="col">Last Updated on</th>
</tr>
</thead>
<tbody id="tbody"></tbody>
</table>
NOTES
There are definitely a lot of different ways to filter() the data and I opted for a very simple includes() method. I also added toLowerCase() to the country and the search string to make it case-insensitive, but I understand there are several ways to do this as well.
let regex = new RegExp(c, "i");
countriesData.filter(country => country.Country.match(regex))
That for example would also return a list of search results that are case-insensitive.

display csv file inside a table using javascript

I have this script that gets the csv file, and separates it by column. I am having trouble to display the values in a table. I can't seem to get each column to create a new table row. Any help will be appreciated as I am not very good at JS.
<script>
getData();
async function getData() {
const response = await fetch('data.csv')
const data = await response.text();
console.log(data);
const table = data.split('\n');
table.forEach(row => {
const columns = row.split(',')
const date = columns[0]
const temp = columns[1]
console.log(date, temp);
})
}
</script>
The data.csv looks something like this:
17-10-2020,25
17-10-2020,25
17-10-2020,25
17-10-2020,25
17-10-2020,25
17-10-2020,25
17-10-2020,25
17-10-2020,25
The console.log(data, temp) returns without the commas. My only problem is trying to get them inside a table using Javascript.
<table class="table text-left mt-2" id="data">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Date/Time</th>
<th scope="col">Temperature</th>
</tr>
</thead>
<tbody>
<!-- Generate the csv table rows here -->
</tbody>
</table>
const tableBody = document.getElementById("table-body");
getData();
async function getData() {
const response = await fetch('data.csv')
const data = await response.text();
console.log(data);
const table = data.split('\n');
table.forEach((row,index) => {
const columns = row.split(',')
const date = columns[0]
const temp = columns[1]
console.log(date, temp);
const tr = document.createElement("tr");
tr.innerHTML = `
<td>${index + 1}</td>
<td>${date}</td>
<td>${temp}</td>
`;
// finally add the <tr> to the <tbody>
tableBody.append(tr);
})
}
<table class="table text-left mt-2" id="data">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Date/Time</th>
<th scope="col">Temperature</th>
</tr>
</thead>
<tbody id='table-body'>
<!-- Generate the csv table rows here -->
</tbody>
</table>
Try this and let me know if its working or not. Please note i've added an ID to the table body and selecting that via ID.

How i can clear/refresh my table before getting new data from api?

I am trying to retrieve datas from an api by triggering a button.but evertimes i click the button the old datas remain exist which i dont want.i want the table will be reloaded and will have new datas from api.
const showData = document.querySelector('.showData')
const btn = document.querySelector('.shwData-btn')
btn.addEventListener('click', showdata)
function showdata(){
fetch('http://localhost:5000/posts')
.then(res => res.json())
.then(data=>{
data.forEach(item =>{
const id = item['_id']
const name = item.name
const email = item.email
const age = item.age
const tr = document.createElement('tr')
tr.innerHTML = `
<tr>
<td>${id}</td>
<td>${name}</td>
<td>${email}</td>
<td>${age}</td>
</tr>
`
showData.appendChild(tr)
})})}
<!-- language: lang-html -->
<button class="shwData-btn">Showdata</button>
<table class="showData">
<tr>
<td>id</td>
<td>email</td>
<td>name</td>
<td>age</td>
</tr>
</table>
You will have to render a blank table or clear all rows(tr) before populating it with data.
const showData = document.querySelector('.showData')
const btn = document.querySelector('.shwData-btn')
btn.addEventListener('click', showdata)
function showdata(){
fetch('http://localhost:5000/posts')
.then(res => res.json())
.then(data=>{
// Clear your table here or populate with blank data
// tbody because you do not want to clear column heading. Make sure you have tbody and theader
$(".showData tbody tr").remove();
data.forEach(item =>{
const id = item['_id']
const name = item.name
const email = item.email
const age = item.age
const tr = document.createElement('tr')
tr.innerHTML = `
<tr>
<td>${id}</td>
<td>${name}</td>
<td>${email}</td>
<td>${age}</td>
</tr>
`
showData.appendChild(tr)
})})}
<!-- language: lang-html -->
<button class="shwData-btn">Showdata</button>
<table class="showData">
<tr>
<td>id</td>
<td>email</td>
<td>name</td>
<td>age</td>
</tr>
</table>
Highly recommend to have a look at this as well:
Delete all rows in an HTML table

Mapping table children content with puppeteer

My goal is to fetch .textContent from different <td> tags, each lying within a separate <tr>.
I think the problem lies within the table variable, as I am not checking the correct variable for children. Currently, data variable is only fetching the first <tr>, so price evaluates with this code. However, volume and turnover does not. I think it is a simple fix but I just can't figure it out!
JavaScript:
try {
const tradingData = await page.evaluate(() => {
let table = document.querySelector("#trading-data tbody");
let tableData = Array.from(table.children);
let data = tableData.map(tradeData => {
console.log(tradeData);
let price = tradeData.querySelector(".quoteapi-price").textContent;
console.log(price);
let volume = tradeData.querySelector("quoteapi-volume").textContent;
console.log(volume);
let turnover = tradeData.querySelector("quoteapi-value").textContent;
console.log(turnover);
return { price, volume, turnover };
})
return data;
});
console.log(tradingData);
} catch (err) {
console.log(err);
}
HTML:
<table id="trading-data" class="qq_table">
<tbody>
<tr class="qq_tr_border_bot">
<td>Price</td>
<td class="qq_td_right quoteapi-number quoteapi-price" data-quoteapi="price">$0.105</td>
</tr>
<tr class="qq_tr_border_bot">
<td>Change</td>
<td class="qq_td_right pos" data-quoteapi="changeSignCSS">
<span data-quoteapi="change (signed)" class="quoteapi-number quoteapi-price quoteapi-change">0.005</span>
<span data-quoteapi="pctChange (pct)" class="quoteapi-number quoteapi-pct-change">(5.00%)</span>
</td>
</tr>
<tr class="qq_tr_border_bot">
<td>Volume</td>
<td class="qq_td_right quoteapi-number quoteapi-volume" data-quoteapi="volume scale=false">5,119,162</td>
</tr>
<tr>
<td>Turnover</td>
<td class="qq_td_right quoteapi-number quoteapi-value" data-quoteapi="value scale=false">$540,173</td>
</tr>
</tbody>
</table>
For example, this should return price="$0.11", volume="3,900,558", turnover="$412,187"
You only need the map function when you are expecting multiple tables or tbodies. As this seems not to be the case in your example, you can do it like this:
const tradingData = await page.evaluate(() => {
let table = document.querySelector("#trading-data tbody");
let price = table.querySelector(".quoteapi-price").textContent;
let volume = table.querySelector(".quoteapi-volume").textContent;
let turnover = table.querySelector(".quoteapi-value").textContent;
return { price, volume, turnover };
});
console.log(tradingData);

Meteor returning NaN in the browser

I'm building a simple ordering app in Meteor and have come a cropper trying to get the order total even though I can get it to log in the console as a bona fide number - it is being rendered as NaN. Any help would be greatly appreciated.
Note the totals of individual products are appearing fine.
I have the following files:
meteorder/client/templates/orders/order_build.js:
Template.order.helpers({
'orderitems': function() {
var orderCart = [];
var orderItems = OrderItems.find({});
var total = 0;
orderItems.forEach(function(orderItem) {
var item = _.extend(orderItem, {});
var product = Products.findOne({
_id: orderItem.product
});
orderItem.productname = product.description;
orderItem.price = (Number(product.price) * orderItem.qty);
total += orderItem.price;
orderCart.push(orderItem);
});
orderCart.subtotal = total;
orderCart.tax = orderCart.subtotal * .23;
orderCart.total = orderCart.subtotal + orderCart.tax;
return orderCart;
}
})
meteorder/client/templates/orders/order_build.html:
<template name="order">
<div class="page-header">
<h1>
<small>My Order</small>
</h1>
</div>
<table class="span4 table table-striped table-bordered table-hover">
<thead>
<th>Qty</th>
<th>Product</th>
<th>Price</th>
<th></th>
</thead>
<tbody>
{{#each orderitems}}
<tr>
<td>{{qty}}</td>
<td>{{productname}}</td>
<td>{{currency price}}</td>
<td><span class="label-important label removeci">X</span></td>
</tr>
{{else}}
<tr>
<td colspan="3">No Products in Order</td>
</tr>
{{/each}}
<tr>
<td class="totalcol" colspan="2">SubTotal:</td>
<td colspan="2">{{currency orderCart.subtotal}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Tax 6%:</td>
<td colspan="2">{{currency orderCart.tax}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Total:</td>
<td colspan="2">{{currency orderCart.total}}</td>
</tr>
</tbody>
</table>
</template>
meteorder/client/lib/main.js:
Template.registerHelper('currency', function(num){
return '€' + Number(num).toFixed(2);
});
meteorder/server/server.js:
Meteor.methods({
addToOrder:function(qty,product,session){
check(qty, Number);
check(product, String);
check(session, String);
if(qty > 0){
OrderItems.insert({qty:qty,product:product,sessid:session});
console.log('reaching this fn', typeof qty, typeof product, typeof session);
} else{
console.log('Quantity is Zero');
}
},
removeOrderItem:function(id){
check(id, String);
OrderItems.remove({_id:id});
console.log('successfully deleted');
}
});
Here is a link to the GitHub repo
And the latest version of the deployed App
Thanks in advance!
Edit:
Just adding this in for Matthias:
Template.productItem.events({
'click .addOrder':function(evt,tmpl){
var qty1 = tmpl.find('.prodqty').value;
var qty = parseInt(qty1);
var product = this._id;
var sessid = Meteor.default_connection._lastSessionId; //stops others adding to your cart etc
Meteor.call('addToOrder',qty, product, sessid);
console.log('this is the quantity:', typeof qty, product, sessid);//stops others ad
}
});
to see if it gives a better picture of why the cart is not populating. Thanks
You're trying to use orderCart as both an array of objects and an object. You push a bunch of orderItem objects on to the array but at the end you attempt to set orderCart.subtotal etc...
Change your helper to have a separate summary object:
var summary = {};
summary.subtotal = total;
summary.tax = summary.subtotal * .23;
summary.total = summary.subtotal + summary.tax;
return {items: orderCart, summary: summary}
Then in your html do:
{{#each orderitems.items}}
...
{{/each}}
Finally in your summary line use {{currency orderitems.summary.tax}} etc...
Your values are rendered as NaN because orderCart is undefined.
You could define a separate helper to fix your code:
Template.order.helpers({
orderItems: function () {
return OrderItems.find().map((orderItem) => {
let product = Products.findOne({
_id: orderItem.product
});
if (product) {
orderItem.productname = product.description;
orderItem.price = calcPrice(product, orderItem);
return orderItem;
}
});
},
orderCart: function () {
let orderCart = {subtotal: 0};
OrderItems.find().forEach((orderItem) => {
let product = Products.findOne({
_id: orderItem.product
});
if (product) orderCart.subtotal += calcPrice(product, orderItem);
});
orderCart.tax = orderCart.subtotal * .23;
orderCart.total = orderCart.subtotal + orderCart.tax;
return orderCart;
}
});
function calcPrice(product, orderItem) {
return (Number(product.price) * orderItem.qty);
}
<template name="order">
<div class="page-header">
<h1>
<small>My Order</small>
</h1>
</div>
<table class="span4 table table-striped table-bordered table-hover">
<thead>
<th>Qty</th>
<th>Product</th>
<th>Price</th>
<th></th>
</thead>
<tbody>
{{#each orderItems}}
<tr>
<td>{{qty}}</td>
<td>{{productname}}</td>
<td>{{currency price}}</td>
<td><span class="label-important label removeci">X</span></td>
</tr>
{{else}}
<tr>
<td colspan="3">No Products in Order</td>
</tr>
{{/each}}
{{#with orderCart}}
<tr>
<td class="totalcol" colspan="2">SubTotal:</td>
<td colspan="2">{{currency orderCart.subtotal}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Tax 6%:</td>
<td colspan="2">{{currency orderCart.tax}}</td>
</tr>
<tr>
<td class="totalcol" colspan="2">Total:</td>
<td colspan="2">{{currency orderCart.total}}</td>
</tr>
{{/with}}
</tbody>
</table>
</template>
Please note: I noticed a lot of missing semicolons. I strongly recommend to fix that, as this may cause several issues on deployment due to Meteor's minifying process.

Categories