In a table, certain input text fields are displayed. Accordingly data could be inputted in it. My intention is to club all the input data into an array. Each record has its specific unique id, which we get in console while we input in text box. Based on this id, I want to club into an array data. I've tried with one logic but gives error. Please have a look at the code below
// Here newData is an array of records which I'm displaying in Grid
const [dataNew, setDataNew] = useState(newData);
const textChange = (data) => {
const { id, value } = data;
setDataNew((prevInfo) => {
const dataIndex = +id[id.length - 1];
return {
...prevInfo,
// Here I'm getting error in the below code snippet in prevInfo
dataHere: Object.assign([...prevInfo.newData], { [dataIndex]: value })
};
});
};
console.log('NEW DATA', newData)
Please suggest me if any changes to be done. Any solution highly appreciated
Please refer codesandbox link --> https://codesandbox.io/s/elated-varahamihira-xpjtdb?file=/src/Table.js:149-197
dataNew is initially an array, but you are returning an object from the setDataNew callback.
Also id is a number itself in your sandbox, so the following would suffice:
const textChange = (data) => {
const { id, value } = data;
setDataNew((prevInfo) => {
const dataIndex = id - 1;
prevInfo[dataIndex] = value;
return [...prevInfo];
});
};
everyone, I have some problem with fetching data and displaying message on initial loading as well as when I change some of the input filed value. The idea here is to display specific message in two cases after doing some calculation.
const potrosnja = document.getElementById('potrosnja');
const nagib = document.getElementById('nagib');
const input = document.querySelectorAll('input[type="number"]');
const submitBtn = document.getElementById('submitBtn');
const poruka = document.getElementById('poruka');
let str = document.querySelector('input[name="strane-sveta"]:checked').value;
let godisnjaPotrosnja = parseInt(potrosnja.value);
let nagibKrovaInput = nagib.value;
//On button submit it fetches data and calculate the value needed for yearly consumption of energy
//fetching data
async function dataFetch(){
let response = await fetch('./csvjson.json')
let data = await response.json();
data.map(strana => {
strana.strana.map((item, i) => {
try {
if(item == str && nagibKrovaInput == strana.nagib) {
let result = Math.ceil(godisnjaPotrosnja / strana.vrednost[i]);
console.log("try works")
poruka.innerHTML = `You need <span class="kw">${result}</span>`
}
}
catch(err) {
poruka.innerHTML = `Please fill required fields.`
console.log(err)
}
})
})
}
//event listeners
submitBtn.addEventListener('click', () => {
dataFetch()
console.log('clicked')
input.forEach(input => {
if(input.value == ''){
input.classList.add("active");
}
})
})
I can see that the problem is inside try function, it like condition isn't treated on initial load, and I have to reload page so it would work. Can someone help me understanding what is the problem?
Ok, I found solution... First thing I have to do Is to check if nagibKrovaInput == strana.nagib, after I get true, I compared does the indexOf item is equal as str and after I get true, it will display something. I also changed on click on the button to send values to data function as an arguments and It solved the problem. Tnx for help.
Okay so I have a website that needs to display some data from a JSON file. The file contains different places in Norway with their name (Halden), state number (kommunenummer), number of men (menn) and number of women (kvinner).
I need to write some code that displays every name, state number and the total population of that place (which is the most recent measurement of men + women)
The JSON data looks like this:
"elementer": {
"Halden": {
"kommunenummer": "0101",
"Menn": {
"2016": 15306,
"2017": 15473,
"2018": 15620
},
"Kvinner": {
"2016": 15238,
"2017": 15317,
"2018": 15417
}
}
And so on... The JSON file has a lot of these. The attribute "elementer" is where all the data is stored, so when I open "elementer" in my browser console, I get all of the states listed.
So this is where I need the JSON data to be displayed;
<div id="visOversikt">
<ul>
<li>hei</li>
</ul>
</div>
My JavaScript looks like this:
function load(url, objekt){
var request = new XMLHttpRequest()
request.open('GET', url, true)
request.onreadystatechange = function () {
if(request.readyState === 4 && request.status === 200) {
console.log("Data er lastet inn vellykket...");
}
}
request.onload = function() {
// Begin accessing JSON data here
objekt.data = JSON.parse(this.response)
}
request.send()
}
var befolkning = {
}
load("http://wildboy.uib.no/~tpe056/folk/104857.json", befolkning)
function getNames(data) {
for (var variable in data) {
console.log(variable)
}
function displayOversikt() {
}
}
The function displayOversikt() is where I thought I could write the code to display the data. If anyone can help I would appreciate it. Say I write getNames(befolkning.data.elementer) in the console, I listed all the state names (if it is of any help).
I have done it in simple jquery.
Your html
<html>
<head>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="JsonView.js"></script>
</head>
<body>
<div id="visOversikt">
<ul></ul>
</div>
</body>
</html>
Your jquery(JsonView.js) would be
$(document).ready(function(){
$.getJSON("http://wildboy.uib.no/~tpe056/folk/104857.json", function(json) {
$.each(json['elementer'],function(key,value){
var stateName = key;
var kommunenummer = value['kommunenummer'];
var MennValue = value['Menn']['2018'];
var FemaleValue = value['Kvinner']['2018'];
var addition = MennValue + FemaleValue;
var li = '<li>'+stateName+', '+kommunenummer+', '+addition+'</li>'
$("#visOversikt ul").append(li)
});
});
})
First of all, I would suggest looking at the fetch API. It's a real improvement on the older AJAX style you use.
Then, I would break the problem down into three phases:
Use fetch to get the data
Restructure the data to include exactly what you want
Format each element of that data into HTML
Here's one way that might look:
const output = document.getElementById('output')
const structureTownData = ([name, {kommunenummer, Menn, Kvinner}]) => ({
name,
kommunenummer,
pop: Number(Menn['2018']) + Number(Kvinner['2018'])
})
const formatOutput = ({name, kommunenummer, pop}) => {
const el = document.createTextNode(`${name} (#${kommunenummer}): ${pop}`)
const li = document.createElement('li')
li.appendChild(el);
output.appendChild(li)
}
fetch("http://wildboy.uib.no/~tpe056/folk/104857.json")
.then(resp => resp.json())
.then(({elementer}) => Object.entries(elementer).map(structureTownData))
.then(towns => towns.forEach(formatOutput))
<ul id="output"></ul>
<script>
data = {"elementer":{"Halden":{"kommunenummer":"0101","Menn":{"2016":15306,"2017":15473,"2018":15620},"Kvinner":{"2016":15238,"2017":15317,"2018":15417}},"Oslo kommune":{"kommunenummer":"0301","Menn":{"2016":328424,"2017":332578,"2018":335806},"Kvinner":{"2016":329966,"2017":334181,"2018":337663}}}}
// fake fetch for testing
const fetch = (url) => Promise.resolve(({json: () => data}))
</script>
There are plenty of alternative ways to create your HTML. And you'd have to decide on the exact format you want. Here I just use an unordered list with elements that look like Halden (#0101): 31037.
Already answered here https://stackoverflow.com/a/20135028/5525384
const div = document.getElementById('visOversikt');
function makeList(jsonObject, listElement){
for(var i in jsonObject){
var newLI = document.createElement('li');
if (jsonObject[i] instanceof Array){
newLI.innerHTML=i;
}
else if (jsonObject[i] instanceof Object){
newLI.innerHTML=i;
}
else {
newLI.innerHTML=i+': '+jsonObject[i];
}
listElement.appendChild(newLI)
if (jsonObject[i] instanceof Array || jsonObject[i] instanceof Object){
var newUL = document.createElement('ul');
listElement.appendChild(newUL);
makeList(jsonObject[i],newUL);
}
}
}
makeList(jsonObject, div);
try to use <template> and split data and view
let data = {"elementer":{"Halden":{"kommunenummer":"0101","Menn":{"2016":15306,"2017":15473,"2018":15620},"Kvinner":{"2016":15238,"2017":15317,"2018":15417}},"Moss":{"kommunenummer":"0104","Menn":{"2016":16000,"2017":16085,"2018":16124},"Kvinner":{"2016":16182,"2017":16322,"2018":16464}}}}
function displayOversikt(data) {
let inject = (s,o)=>s.replace(/\${(.*?)}/g,(x,g)=>o[g]); // helper which inject object fields into string in ${filedname}
// Prepare data
let dd= Object.entries(data.elementer).map(([x, y]) => {
let year = Object.keys(y.Menn).sort((a,b)=>+b-a)[0]; // last year
return {
population: y.Menn[year] + y.Kvinner[year],
num: y.kommunenummer,
name: x,
}});
// Read templae string
let t=item.innerHTML;
// Bind data to template and write in content element
content.innerHTML = dd.map(x=> inject(t,x)).join('');
}
displayOversikt(data);
<div ><ul id="content"></ul></div>
<template id="item">
<li>${name}, ${num}, ${population}</li>
</template>
I want to rerun the search or populate the results as if the user never left.
So I visit the page, search for cats and get some results based on cats. I close the tab, come back later, and rather than find myself on a fresh page that has no results, I’m provided with the results from my last search. I am only allowed to use Javascript and local storage to achieve this. Here is my JS file:
var search = document.getElementById('searchTerm');
if(!localStorage.getItem('input')) {
populateStorage();
}
// To set the event to listen to
const form = document.querySelector('.js-search-form');
// To listen when user hits submit or press enter
form.addEventListener('submit', (e) => {
// Start of the query string
const base = `https://api.themoviedb.org/3/search/movie?include_adult=false&page=1&`;
// Extension of the query string
const searchTerm = document.querySelector('#searchTerm').value;
const language = `en-US&`;
const api_key = `7ab3cb18b4ad4a07bbd8bb01acfa7091`;
// The complete build of the url
const url = `${base}query=${searchTerm}&language=${language}api_key=${api_key}`;
// The get method
const option = {
method: 'GET'
}
// Stops the default action
e.preventDefault()
fetch(url)
//Parse data
.then( response => {
if (response.ok) {
return response.json()
} else {
throw response
}
})
// Do something with data
.then( data => {
console.log(data)
// Output results
let resultElement = '';
if(data.results.length > 1) {
resultElement += `
<h2><span>Results for ${searchTerm}</span></h2>
<section class="js-search-results clearfix">
`;
if(data.results) {
data.results.forEach(function(results){
resultElement += `<article class="item">
<div class="container">
<img src="https://image.tmdb.org/t/p/w500${results.poster_path}"/>
<div class="content">`;
if(results.title.length > 17) {
resultElement += `<h3>${results.title.substr(0,17)}...</h3>`;
} else {
resultElement += `<h3>${results.title}</h3>`;
}
resultElement += `<p>Released: ${results.release_date}</p>`;
resultElement += `</div>
</div>
</article>`;
});
resultElement += `</section>`;
populateStorage()
} else {
resultElement += '<p class="no-results">No results</p>';
}
document.querySelector('.js-search-results').innerHTML = resultElement;
}
})
.catch(err => {
console.log(err)
})
})
function populateStorage() {
localStorage.setItem('searchTerm', document.getElementById('searchTerm').value);
}
EDIT -
You are calling localStorage.getItem('input'); but you are saving the local storage item as searchTerm please make these names consistent with one another
you either need to change localStorage.getItem('input')
TO
localStorage.getItem('searchTerm');
OR
change localStorage.setItem('searchTerm', document.getElementById('searchTerm').value)
TO
localStorage.setItem('input', document.getElementById('searchTerm').value)
-Edit-
Assuming that this is wrapped in a document ready function, update your initial check of storage to look like this...
var search = document.getElementById('searchTerm');
//This assumes that you corrected your getItem to reference 'searchTerm'
if(!localStorage.getItem('searchTerm')) {
populateStorage();
}
else {
search.value = localStorage.getItem('searchTerm');
}
Your code never makes a call to actually populate that field so this should fix that.
i have a data structure as below
I created an array called new array with the IDs such as [19777873, 53399293]
var dbRef = firebase.database().ref().child('Agents').child(newarray[i]);
dbRef.on('value', snapshot => {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
database = firebase.database();
console.log("Testing if the array values are here \n" + newarray);
// var dbRef = firebase.database().ref().child('Agents').child(newarray[i]);
dbRef.on('value', newAgents, errData);
}
})
}
New Agent function
function newAgents(data) {
var container = document.getElementById("team");
container.innerHTML = '';
data.forEach(function(AgentSnap) { // loop over all jobs
var key = AgentSnap.AgentID;
console.log(AgentSnap.key);
var Agents = AgentSnap.val();
var AgentCard = `
<div class= "profilepics" id="${key}">
<figure ><img src=${Agents.profilepicurl}><figcaption>${Agents.Fname}</figcaption></figure>
</div>
`;
container.innerHTML += AgentCard;
})
}
the problem I'm having now is that images(from {Agents.profilepicurl}) are being displayed and name (from {Agents.Fname}) are not being displayed. instead of name it shows "undefined" and no error is show in console. What am I doing wrong and how can I fix this?
There are some strange things happening in the first few lines of your code. You are setting the "on" listener twice (ignoring the resulting snapshot for the first listener), and you're awaiting authentication and setting a database object without using it. I am not absolutely certain about what you're trying to achieve, but would this work? It's a simplified version of what I think you're trying to do with the current code:
console.log("Testing if the array values are here \n" + newarray);
firebase.auth().onAuthStateChanged((user) => {
if (user) {
document.getElementById("team").innerHTML = '';
database = firebase.database();
for (agentId of newarray) {
var dbRef = database.ref().child('Agents').child(newarray[i]);
dbRef.on('value', newAgents);
}
}
})
function newAgents(AgentSnap) {
var container = document.getElementById("team");
var key = AgentSnap.AgentID;
console.log(AgentSnap.key);
var Agent = AgentSnap.val();
var AgentCard = `
<div class= "profilepics" id="${key}">
<figure ><img src=${Agent.profilepicurl}><figcaption>${Agent.Fname}</figcaption></figure>
</div>
`;
container.innerHTML += AgentCard;
}