Get elements from JSON array to display as a text - javascript

So i am trying to get a first_name from JSON object which has array of elements by iterating through it, for example if i type 'Ron' it will display as a text but for some reason I can't get display it as a text unless i send in a respond this `
playerName: nbaPlayer[0]
But it only displays one element as a text since others are not in a response
reponse in a server enter image description here
Here is a code for fetch where i use search bar from handlebars to search for a first_name
const nbaForm = document.querySelector('form')
const search = document.querySelector('input')
const messageOne = document.querySelector('#player-1')
nbaForm.addEventListener('submit', (event) => {
event.preventDefault()
const playerSearch = search.value
messageOne.textContent = 'Loading...'
fetch('http://localhost:4000/nba').then((response) => {
response.json().then(nbaData => {
if (nbaData.playerName === playerSearch) {
messageOne.textContent = nbaData.playerName
} else {
messageOne.textContent = 'not found'
}
})
})
})
request method
app.get('/nba', (req,res) => {
networkManager.nbaPlayerData((data)=>{
/
var nbaPlayer = []
for(var i=0; i<data.data.length; i++){
nbaPlayer.push(data.data[i].first_name)
}
console.log(nbaPlayer)
res.send({
playerName: nbaPlayer
})
})
})
handlebars file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NBA</title>
<link rel = "stylesheet" href="/css/style.css">
</head>
<body>
<div class="main-content">
<h1>NBA SERVER</h1>
<p>Use this site to get NBA player</p>
<form action="">
<input placeholder="Type a players name">
<button>Search</button>
</form>
<p id="player-1"></p>
<h1>{{playerName}}</h1>
</div>
<script src ="/js/fetch-app.js"></script>
</body>
</html>

try this.
fetch('http://localhost:4000/nba').then((response) => {
response.json().then(nbaData => {
var index = nbaData.playerName.indexOf(playerSearch)
if (index !== -1) {
messageOne.textContent = nbaData.playerName[index]
} else {
messageOne.textContent = 'not found'
}
})
})

You are getting an array from
res.send({
playerName: nbaPlayer // nbaPlayer is array
})
but in your fetch, you want to get data as from simple object

Related

If I don't choose a file and press the send button, I will get a popup but it'll break any future popups

If I press Send ☞ without choosing a file, it'll say "No file selected." in a little Bootstrap warning alert but it seems to break all future alerts like file uploaded or file already exists on disk.
If I make an error alert like file already on disk, it'll work and won't break future alerts (meaning it won't stop alerts that popup in the future from showing).
So, why is the "No file selected" alert breaking other alerts?
In this clip, you can see me trying to make more than one of that alert but it just doesn't want to.
Here is my ejs file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Androp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
</head>
<body>
<div class="container-fluid">
<p>
<h1>Androp - Send to [...] MBP</h1>
</p>
<div class="input-group mb-3">
<button class="btn btn-outline-primary" type="button" onclick="send()">Send ☞</button>
<input type="file" class="form-control" id="fileSelector">
</div>
<div id="alerts"></div>
<div class="text-center">
<div id="spinny" class="spinner-border" style="width: 3rem; height: 3rem; visibility: hidden;"></div>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io()
const engine = socket.io.engine
let maxSize = 0
let sending = false
socket.on("disconnect", (reason) => {
alert(`Disconnected from laptop! Check your internet or refresh the page. πŸ’€ (${reason})`, "warning")
})
engine.on("close", reason => {
console.log(reason)
})
socket.emit("getMaxSize", (size) => {
return maxSize = size
})
const alert = (message, type) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = [
`<div class="alert alert-${type} fade show" role="alert">`,
` <div>${message}</div>`,
'</div>'
].join('')
document.getElementById("alerts").append(wrapper)
return bootstrap.Alert.getOrCreateInstance(wrapper)
}
function send() {
if (sending) {
return false
}
sending = true
const file = document.getElementById("fileSelector").files[0] || false
function close(alert) {
setTimeout(() => {
alert.close()
}, 3500)
}
if (!file) { return close(alert("No files to upload.", "warning")) }
if (file.size >= maxSize) { return close(alert(`File is bigger than ${Math.round(maxSize / (1024 ** 2))} MB`, "danger")) }
document.getElementById("spinny").style.visibility = 'visible'
socket.timeout(10000).emit("upload", file, file.name, file.size, (err, status) => {
if(err) {
return close(alert("Could not contact laptop within 10s, laptop might be in sleep mode. πŸ’€", "warning"))
}
document.getElementById("spinny").style.visibility = 'hidden'
sending = false
return close(alert(status.message, status.success ? "success" : "danger"))
})
}
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/#popperjs/core#2.11.5/dist/umd/popper.min.js"
integrity="sha384-Xe+8cL9oJa6tN/veChSP7q+mnSPaj5Bcu9mPX5F5xIGE0DVittaqT5lorf0EI7Vk"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/js/bootstrap.min.js"
integrity="sha384-ODmDIVzN+pFdexxHEHFBQH3/9/vQ9uori45z4JjnFsRydbmQbmL5t1tQ0culUzyK"
crossorigin="anonymous"></script>
</body>
</html>
You should move the flag sending = true when you actually plan to send after validation. I would also place sending = false right when callback returns, even if err
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Androp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
</head>
<body>
<div class="container-fluid">
<p>
<h1>Androp - Send to [...] MBP</h1>
</p>
<div class="input-group mb-3">
<button class="btn btn-outline-primary" type="button" onclick="send()">Send ☞</button>
<input type="file" class="form-control" id="fileSelector">
</div>
<div id="alerts"></div>
<div class="text-center">
<div id="spinny" class="spinner-border" style="width: 3rem; height: 3rem; visibility: hidden;"></div>
</div>
</div>
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js" integrity="sha384-7EyYLQZgWBi67fBtVxw60/OWl1kjsfrPFcaU0pp0nAh+i8FD068QogUvg85Ewy1k" crossorigin="anonymous"></script>
<script>
const socket = io()
const engine = socket.io.engine
let maxSize = 0
let sending = false
socket.on("disconnect", (reason) => {
alert(`Disconnected from laptop! Check your internet or refresh the page. πŸ’€ (${reason})`, "warning")
})
engine.on("close", reason => {
console.log(reason)
})
socket.emit("getMaxSize", (size) => {
return maxSize = size
})
const alert = (message, type) => {
const wrapper = document.createElement('div')
wrapper.innerHTML = [
`<div class="alert alert-${type} fade show" role="alert">`,
` <div>${message}</div>`,
'</div>'
].join('')
document.getElementById("alerts").append(wrapper)
return bootstrap.Alert.getOrCreateInstance(wrapper)
}
function send() {
if (sending) {
return false
}
const file = document.getElementById("fileSelector").files[0] || false
function close(alert) {
setTimeout(() => {
alert.close()
}, 3500)
}
if (!file) {
return close(alert("No files to upload.", "warning"))
}
if (file.size >= maxSize) {
return close(alert(`File is bigger than ${Math.round(maxSize / (1024 ** 2))} MB`, "danger"))
}
sending = true
document.getElementById("spinny").style.visibility = 'visible'
socket.timeout(10000).emit("upload", file, file.name, file.size, (err, status) => {
if (err) {
return close(alert("Could not contact laptop within 10s, laptop might be in sleep mode. πŸ’€", "warning"))
}
document.getElementById("spinny").style.visibility = 'hidden'
sending = false
return close(alert(status.message, status.success ? "success" : "danger"))
})
}
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
</body>
</html>

set_flashdata not working when reloading using javascript

I'm working on a project using codeigniter 3 to send data to a function using POST fetch where it would set a flashdata in the end. but the flashdata doesn't show when I reloaded the page using javascript. why is that?
this is my code:
HTML & javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<?php pre($this->session->keep_flashdata('asd') ?: 'empty');?>
<form method="post" action="" id="form1">
<input type="hidden"
id="csrf"
name="<?=$this->data['csrf_name'];?>"
value="<?=$this->data['csrf'];?>"
/>
<input type="text" name="input1" />
<input type="submit" id="btnSubmit" value="Kirim">
</form>
<script>
const btnSubmit = document.querySelector('#btnSubmit');
btnSubmit.addEventListener('click', function(e) {
e.preventDefault();
const myform = document.querySelector('#form1');
let fd = new FormData(myform);
fetch('/test/test11', {
method: 'POST',
body: fd
})
.then(response => response.json())
.then(res => {
console.log('res', res);
if (res.status) {
window.location.href = window.location.href;
}
})
});
</script>
</body>
</html>
PHP
public function test11($param = '')
{
$this->load->library('My_validations');
$conf_uploader = $this->config->load('uploader_settings', true);
if ($this->input->server('REQUEST_METHOD') == 'POST') {
$this->session->set_flashdata('asd', 'qwerty');
$response = [
'status' => 1,
'msg' => 'asdasd',
];
echo json_encode($response);
return;
}
$this->data['conf_uploader'] = $conf_uploader;
$this->load->view('myform', $this->data);
}
// end public function test11

How can I display the results of a users' search/query in HTML/UI? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
I want to return the results of the users’ search in HTML. The results will vary depending on what value they type in. How can I get my code to display the data from whatever the value of {NameOfData} is?
Myscript.js
function GetData(e){
const nameOfData = e.target.value;
const url = `http://container:8004/v1/data/${nameOfData}`;
//http request
fetch(url,)
.then(res => res.json())
.then (json => console.log(JSON.stringify(json)))
const input = document.getElementById("input");
input.addEventListener("change", GetData);
Index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<form id="form" role="search">
<input type="search" id="input" name="q" placeholder="Search Entities...">
<button>Search</button>
</form>
<script src="myScript.js">
</script>
</body>
</html>
There are only two options for them to input/search for: site and country.
This is what the returned value will look like if {NameOfData} is site:
[
{
"id": "4833e18248616a04ee29b4dd08dd68abfa049ad720489677533c8507a95e7335",
"url": "http://container:8004/v1/data/site/4833e18248616a04ee29b4dd08dd68abfa049ad720489677533c8507a95e7335",
"type": "site",
"name": "Head-Smashed-In Buffalo Jump",
"legal": [
{
"type": "attribution",
"text": "Data is supplied by Wikipedia",
"link": "https://en.wikipedia.org/"
}
]
},
This is what the returned value will look like if the {NameOfData} is Country:
[
{
"id": "5c02434187bc31589f270ae33efb56cbcc43ac0ffcc80d03b42990a0eb61a168",
"url":http://container:8004/v1/data/country/5c02434187bc31589f270ae33efb56cbcc43ac0ffcc80d03b42990a0eb61a168",
"type": "country",
"name": "Afghanistan",
"legal": [
{
"type": "attribution",
"text": "Data is supplied by Wikipedia",
"link": "https://en.wikipedia.org/"
}
]
},
index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
</head>
<body>
<form id="form" role="search">
<input
type="search"
id="input"
name="q"
placeholder="Search Entities..."
/>
<!-- button>Search</button -->
</form>
<div>
<ul style="list-style: none" id="results"></ul>
</div>
<script src="yourScript.js"></script>
</body>
</html>
yourScript.js
const createAndAppendDOM = (DOMChild, objDOMParameters, parent) => {
// argument -> objDOMParameters must be object with parameters of HTML tag -> example { id: 'myId', textContent: 'example' }
const DOMCreated = document.createElement(DOMChild);
if(Object.keys(objDOMParameters).length === 0 ) {
return {
created: false,
error: "Object is empty"
};
}else {
for(let parameter in objDOMParameters) {
DOMCreated[parameter] = objDOMParameters[parameter];
}
}
parent.appendChild(DOMCreated);
}
function GetData(e) {
e.preventDefault();
const nameOfData = e.target.value;
//const url = `http://container:8004/v1/data/${nameOfData}`;
const url = "https://my-json-server.typicode.com/typicode/demo/posts";
//http request
fetch(URL)
.then(res => res.json())
.then(
json => {
//console.log(json);
json.forEach(element => {
createAndAppendDOM('li', { textContent: ` ${element['title']} ` }, results);
});
})
}
// I don't know what for you have button tag and what for if you have listener - change - to input
// its not make sense
// so what do you want to do when you append listener to button - click - for submit?
// If you want to use listener like - change - so you maybe delete button in you HTML code, because your code will execute when you escape from input tag
const results = document.querySelector("ul");
console.log(results);
const input = document.querySelector("input");
input.addEventListener("change", GetData);

Is it possible to create a global Ejs component?

As you can see I included my navbar component in my index.ejs file and I am doing the same thing with every other file I have, like user page for example. Is there any way that I can use my navbar component in all of my ejs files by including it somewhere once? instead of including it separately in each ejs file?
Right now I am doing this in every one of my files:
index.ejs:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<% include components/navbar %>
rest of the code...
</body>
</html>
as you requested in comments , this is my way to do it :
i have "views" folder in project including these folders inside :
Assets
Layouts
and dynamic ejs files beside them
let's say we want to render this layout which has a header in each page , but with different body :
layout :
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<% for (let cssLink of cssLinks) { %>
<link rel="stylesheet" href="<%= cssLink %>" />
<% } %>
<title>home page</title>
</head>
<body>
<h1>THIS IS HEADER!</h1>
<div id="demo">
<%- mainView %>
</div>
</body>
</html>
you can see there is a variable mainView in the body , so let's see how can we insert our dynamic body there :
i have a function inside my utility folder which reduces the repeat of code :
const ejs = require('ejs');
const path = require('path');
const layoutsPath = path.join(__dirname, "./../views/layouts/");
const assetsPath = path.join(__dirname, "./../views/assets/");
const viewsPath = path.join(__dirname, './../views/');
const load = (basePath, filename, data, cb = null) => {
let route ;
switch (basePath) {
case 'layout': {
route = layoutsPath;
break;
}
case 'asset': {
route = assetsPath;
break;
}
case 'view': {
route = viewsPath;
break;
}
default: {
route = basePath;
}
}
ejs.renderFile(path.join(route, filename), data, (err, str) => {
if (err) {
console.log(err);
return err;
}
if (cb === null) {
return str;
} else {
return cb(str);
}
});
}
module.exports = {
load
}
now in the index.js i want to output my home.ejs inside my header.ejs to the client :
let allUsers = await usersModule.findAll();
let renderedHTML = '';
load('view', 'home.ejs', { allUsers }, (rendered) => {
load('layout', 'header.ejs', { mainView: rendered, cssLinks: ['/css/header.css'] }, (fullView) => {
renderedHTML = fullView;
});
});
res.status(200).send(renderedHTML);
so here i am getting my required data for my body from database , passing it to the home.ejs , there i loop and render my body view , e.x for home.ejs :
<div>
<% for (let user of allUsers) { %>
<ul>
<li>email : <%= user.email %></li>
<li>name : <%= user.name %></li>
</ul>
<% } %>
</div>
rendered body is passed to our callback as parameter , we can pass it to our header now with variablename mainView , so in the header, the entire rendered body will be insert in the right place in our layout .
now our layout and dynamic body have merged and are ready to be sent to the client

Trying to add a 2 character state code to my National Parks project

In my search, when I add states such as Michigan or Ohio it returns back National State Parks this part works fine. My problem is that when you just add the State abbreviation it doesn't work so well.
In the API documentation, I can add 'stateCode A comma delimited list of 2 character state codes.' at which I have. In turn it spits out a CURL at which I am not familiar with at all. This is the curl: curl -X GET "https://developer.nps.gov/api/v1/parks?stateCode=AK%2C%20AL%2C%20AR%2C%20AZ%2C%20CA%2C%20CO%2C%20CT%2C%20DC%2C%20DE%2C%20FL%2C%20GA%2C%20HI%2C%20IA%2C%20ID%2C%20IL%2C%20IN%2C%20KS%2C%20KY%2C%20LA%2C%20MA%2C%20MD%2C%20ME%2C%20MI%2C%20MN%2C%20MO%2C%20MS%2C%20MT%2C%20NC%2C%20ND%2C%20NE%2C%20NH%2C%20NJ%2C%20NM%2C%20NV%2C%20NY%2C%20OH%2C%20OK%2C%20OR%2C%20PA%2C%20RI%2C%20SC%2C%20SD%2C%20TN%2C%20TX%2C%20UT%2C%20VA%2C%20VT%2C%20WA%2C%20WI%2C%20WV%2C%20WY&api_key=VBJvAbqe0D9w3pyhaHcw4p4MB2dNgSgxMjvCbyEH" -H "accept: application/json"
How can I add this to my javascript to make this work when I just want to put in the 2 character state abbreviation?
"use strict";
const apiKey = "VBJvAbqe0D9w3pyhaHcw4p4MB2dNgSgxMjvCbyEH";
const searchURL = "https://api.nps.gov/api/v1/parks";
function formatQueryParams(params) {
const queryItems = Object.keys(params).map(
key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
);
return queryItems.join("&");
}
function displayResults(responseJson) {
// if there are previous results, remove them
console.log(responseJson);
$("#results-list").empty();
// iterate through the items array
for (let i = 0; i < responseJson.data.length; i++) {
// for each park object in the items
//array, add a list item to the results
//list with the park title, description,
//and thumbnail
$("#results-list").append(
`<li><h3>${responseJson.data[i].fullName}</h3>
<p>${responseJson.data[i].description}</p>
<a href='${responseJson.data[i].url}'>${responseJson.data[i].url}</a>
</li>`
);
}
//display the results section
$("#results").removeClass("hidden");
}
function getNationalParksInfo(query, maxResults = 10) {
const params = {
key: apiKey,
q: query,
limit: maxResults - 1
};
const queryString = formatQueryParams(params);
const url = searchURL + "?" + queryString;
console.log(url);
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error(response.statusText);
})
.then(responseJson => displayResults(responseJson))
.catch(err => {
$("#js-error-message").text(`Something went wrong: ${err.message}`);
});
}
function watchForm() {
$("form").submit(event => {
event.preventDefault();
const searchTerm = $("#js-search-term").val();
const maxResults = $("#js-max-results").val();
getNationalParksInfo(searchTerm, maxResults);
});
}
$(watchForm);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>National Parks by Location</title>
<link rel="stylesheet" href="style.css" />
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"
></script>
</head>
<body>
<div class="container">
<h1>Your National Parks</h1>
<form id="js-form">
<label for="search-term">Search term</label>
<input type="text" name="search-term" id="js-search-term" required />
<label for="max-results">Maximum results to return</label>
<input
type="number"
name="max-results"
id="js-max-results"
value="10"
/>
<input type="submit" value="Go!" />
</form>
<p id="js-error-message" class="error-message"></p>
<section id="results" class="hidden">
<h2>Search results</h2>
<ul id="results-list"></ul>
</section>
</div>
<script src="app.js"></script>
</body>
</html>
The desired outcome is for me to either type the full state name of the state abbreviation and I get the same search results.

Categories

Resources