I have worked on this problem for quite some time and I am at a lost on how to continue forward. I am trying to return a description of a stock when a certain symbol is entered into the input field. The console.log returns the value of the description when a symbols are entered but it doesn't render it to the page. I have tried to return the whole statement including the map function but that just cancels out my other return statement. I don't know what else to do. Can someone point me in the right direction?
Here is my code:
render() {
const { stockSymbol, userInput } = this.state
stockSymbol.map((stock, i) => {
if (userInput === stock.symbol) {
return <h2 className="symboldescription" key={i}>
{stock.description}
</h2>,
console.log(stock.description + " match")
}
})
return (
<div className="enterstock">
<h1 className="title">Enter Stock Symbol</h1>
<span className="symbol">{this.state.userInput}</span>
<form className="inputfields" onSubmit={this.getSymbol}>
<input type="text" className="symfields" name="symbolname" onChange={this.typeSymbol}></input>
<button type="submit" className="btn">Send</button>
</form>
</div >
)
}
}
You should be including it as part of the return statement for the render method. For example,
render() {
const { stockSymbol, userInput } = this.state;
return (
<div className="enterstock">
<h1 className="title">Enter Stock Symbol</h1>
<span className="symbol">{this.state.userInput}</span>
<form className="inputfields" onSubmit={this.getSymbol}>
<input type="text" className="symfields" name="symbolname" onChange={this.typeSymbol}></input>
<button type="submit" className="btn">Send</button>
</form>
{stockSymbol.map((stock, i) => {
if (userInput === stock.symbol) {
return <h2 className="symboldescription" key={i}>
{stock.description}
</h2>
}
})}
</div>
)
}
the return of your map is not assigned to a variable. You can assign to a variable, and then use in your return of component. something like this:
let description = stockSymbol.map((stock, i) => {
if (userInput === stock.symbol) {
return <h2 className="symboldescription" key={i}>
{stock.description}
</h2>,
console.log(stock.description + " match")
}
})
and then use in the return of component
return (
<div className="enterstock">
<h1 className="title">Enter Stock Symbol</h1>
<span className="symbol">{this.state.userInput}</span>
<form className="inputfields" onSubmit={this.getSymbol}>
<input type="text" className="symfields" name="symbolname" onChange={this.typeSymbol}></input>
<button type="submit" className="btn">Send</button>
</form>
{description}
</div >
)
Related
I'm trying to achieve a Form where first you see 2 and then when you click a button, you see other Input.
I'm using a switch where based on a value I return the first 2 or the others.
I've tried returning only the , returning a form with the inputs but everything gives me the same problem. After i fill the first two text input, when i switch to the others, the first 2 of those input has the values of the previous 2 input.
Thanks for your help.
Here there is a basic version of the code
function renderSwitch() {
switch (currentPhase) {
case 0:
return (
<div>
<input name='email' type='email' placeholder='Inserisci email' />
</div>
);
break;
case 1:
return (
<div>
<input
name='surname'
type='text'
placeholder='Inserisci Cognome...'
/>
</div>
);
break;
}
return (
<div
className='registerpage'
style={{ height: '100vh', backgroundColor: 'white' }}
>
<div className='formdiv'>
<form onSubmit={handleSubmit}>
{renderSwitch()}
{currentPhase < 1 && (
<button onClick={() => nextPhase()}>Next</button>
)}
{currentPhase > 0 && (
<button onClick={() => previousPhase()}>Back</button>
)}
<br />
<button type='submit'>Iscriviti</button>
</form>
</div>
</div>
);
}
You should store the input values using a state:
const [email, setEmail] = useState('')
const [surname, setSurname] = useState('')
function renderSwitch() {
switch (currentPhase) {
case 0:
return (
<div>
<input value={email} name='email' type='email' placeholder='Inserisci email' />
</div>
);
break;
case 1:
return (
<div>
<input
value={surname}
name='surname'
type='text'
placeholder='Inserisci Cognome...'
/>
</div>
);
break;
}
}
And then reset them once you have submitted your data:
function handleSubmit(e) {
e.preventDefault()
// Handler your data...
setEmail('')
setSurname('')
}
I want to check inputs for emptiness on button click. I am filtering an array if one of the inputs is empty. I'm trying to add an error to the array for errors, My task is that I need to add an error only for those inputs that are empty, but the problem is that the error is added even for those inputs that are not empty.
<template>
<form>
<div v-for="(learning, i) in general.learnings" :key="i">
<input
type="text"
v-model="general.learnings[i]"
maxlength="120"
/>
</div>
<p
style="background: red"
v-for="(i, index) in errorList"
:key="'A' + index"
>
{{ i }}
</p>
<button #click="save">Save</button>
</form>
</template>
<script>
export default {
methods: {
save(e) {
this.general.learnings.filter((e, index) => {
if (!e[index]) {
this.errorList.push("Error")
} else if (e[index] !== "") {
this.errorList = [""];
}
});
e.preventDefault();
},
},
data() {
return {
errorList: [],
general: {
learnings: ["", ""],
},
};
},
};
</script>
I think that the problem lies in this.errorList.push("Error") you can look at this code in codesandbox you can write something in the input press the button after pressing delete and press again you will see that everything works awfully, I will be very glad if help with this
I applied #flaxon code where the error will only show for my index then I slightly changed the validation check inside the save method
<div v-for="(learning, i) in general.learnings" :key="i">
<input type="text" v-model="general.learnings[i]" maxlength="120" />
<p style="background: red" :key="'A' + index">
{{ errorList[i] }}
</p>
</div>
save(e) {
this.errorList = [];
this.general.learnings.filter((e, index) => {
if (e === "") {
this.errorList.push("Error");
} else {
return true;
}
});
e.preventDefault();
},
https://codesandbox.io/s/happy-sun-8z8xg
I changed the p to be in the div, and only display the error of that index
<div v-for="(learning, i) in general.learnings" :key="i">
<input type="text" v-model="general.learnings[i]" maxlength="120" />
<p style="background: red" :key="'A' + index">
{{ errorList[i] }}
</p>
</div>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I just want to get the data of First Name which is entered in Input field. And render the HTML of the searched name.
$.getJSON("https://www.hatchways.io/api/assessment/students", fetchData);
var input = `<input type="text" placeholder="Search Here">`;
function fetchData(data) {
const profile = ` <div class="container">
<p id="input">${input}</p>
${data.students
.map(
data =>
`
<div class="profile">
<img src="${data.pic}">
<div id="display">
<h1 id="name" style="font-size:50px">${data.firstName}</h1>
<p>Email: ${data.email}</p>
<p>Company: ${data.company}</p>
<p>Skill: ${data.skill}</p>
<p>Grades: ${data.grades}</p></div>
</div>`
)
.join(" ")}
</div> </div>`;
document.body.innerHTML = profile;
}
const allData = $.get("https://www.hatchways.io/api/assessment/students")
// Customise your search function here, perhaps use a RegEx
function match(a, b) {
return a.toLowerCase().startsWith(b.toLowerCase())
}
// This just filters the data using the search function above
function getData(search) {
const data = allData.responseJSON && allData.responseJSON.students || [];
return data.reduce(
(acc, s) => match(s.firstName, search) ? (acc || []).concat(s) : acc,
[]
);
}
// Abstracting this into another function to keep the code clean
function renderStudent(data) {
return `
<div class="profile">
<img src="${data.pic}">
<div id="display">
<h1 id="name" style="font-size:50px">${data.firstName}</h1>
<p>Email: ${data.email}</p>
<p>Company: ${data.company}</p>
<p>Skill: ${data.skill}</p>
<p>Grades: ${data.grades}</p>
</div>
</div>
`;
}
// Get results when a search is made
// Could use `$('#search').on('keyup', function ...)` for better response, instead of waiting
// for the user to press ENTER
$('#search').change(function(e) {
$('.results').html(getData($(e.currentTarget).val()).map(renderStudent).join())
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<p><input type="text" id="search" placeholder="Search Here" /></p>
<div class="results" />
</div>
You just need to add a doSearch function to filter your search value. Maybe it's not the best practice to resolve your question, but it would give you idea to resolve the problem.
var myData = null;
$.getJSON("https://www.hatchways.io/api/assessment/students", fetchData);
var input = `<input id="searchValue" type="text" placeholder="Search Here"><input type="button" value="search" onclick="doSearch()" />`;
function fetchData(data) {
myData = data;
renderAllHtml(data);
}
function doSearch() {
var searchValue = $('#searchValue').val();
if (searchValue) {
myData.students.forEach(item=>{
if (searchValue === item.firstName) {
renderFilterHtml(item);
}
})
}else {
renderAllHtml(myData);
}
}
function renderFilterHtml(data) {
const profile = ` <div class="container"><p id="input">${input}</p>
<div class="profile">
<img src="${data.pic}">
<div id="display">
<h1 id="name" style="font-size:50px">${data.firstName}</h1>
<p>Email: ${data.email}</p>
<p>Company: ${data.company}</p>
<p>Skill: ${data.skill}</p>
<p>Grades: ${data.grades}</p></div>
</div>
</div> </div>`;
document.body.innerHTML = profile;
$('#searchValue').val(data.firstName);
}
function renderAllHtml(data) {
const profile = ` <div class="container"><p id="input">${input}</p>
${data.students
.map(
data =>
`
<div class="profile">
<img src="${data.pic}">
<div id="display">
<h1 id="name" style="font-size:50px">${data.firstName}</h1>
<p>Email: ${data.email}</p>
<p>Company: ${data.company}</p>
<p>Skill: ${data.skill}</p>
<p>Grades: ${data.grades}</p></div>
</div>`
)
.join(" ")}
</div> </div>`;
document.body.innerHTML = profile;
}
constructor(props) {
super(props);
this.submitQA = this.submitQA.bind(this);
this.onSearchChange = this.onSearchChange.bind(this);
this.isSearched = this.isSearched.bind(this);
this.answerSubmitted = this.answerSubmitted.bind(this);
this.reset = this.reset.bind(this);
this.state = {
answers: [],
answer: '',
searchTerm: '',
}
}
reset() {
console.log("reset");
}
render() {
const answer = true;
return (
<div className="App">
<div className="center">
<form >
Search: <input type="text" onChange={this.onSearchChange} /><br/>
</form>
<form onSubmit={this.submitQA}>
Q & A:
<input type="text" placeholder=" Course/Q/A"/>
<button type="submit"> Submit </button>
</form>
<span>{basicFormat}</span>
</div>
{
this.state.answers.filter(this.isSearched(this.state.searchTerm)).map((item) => {
return (
if(answer) {
this.reset;
}
<div>
<form onSubmit={this.answerSubmitted}>
<text> {item} </text>
<input type="text" placeholder="answer the question"/>
</form>
</div>
)
})
}
</div>
);
}
Why can't I use any logic in this render method? Keeps giving me unexpected token. Do not see anything wrong with it. Looked at some tutorials and they are doing the exact same thing but why is mine throwing me an error?
You've included a Javascript if statement inside the return, mixed with the JSX.
Quoting the React documentation:
if statements and for loops are not expressions in JavaScript, so they can't be used in JSX directly. Instead, you can put these in the surrounding code.
To fix the unexpected token error, move the if statement before the return:
{
this.state.answers.filter(this.isSearched(this.state.searchTerm)).map((item) => {
if(answer) {
this.reset();
}
return (
<div>
<form onSubmit={this.answerSubmitted}>
<text> {item} </text>
<input type="text" placeholder="answer the question"/>
</form>
</div>
)
})
}
I would also recommend that you perform the mapping before the return in the render function. That way, the rendering is more clearly separated from the data manipulation.
render() {
const answer = true;
const answerForms = this.state.answers
.filter(this.isSearched(this.state.searchTerm))
.map((item) => {
if (answer) {
this.reset()
}
return (
<div>
<form onSubmit={this.answerSubmitted}>
<text> {item} </text>
<input type="text" placeholder="answer the question" />
</form>
</div>
)
})
return (
<div className="App">
<div className="center">
<form >
Search: <input type="text" onChange={this.onSearchChange} /><br />
</form>
<form onSubmit={this.submitQA}>
Q & A:
<input type="text" placeholder=" Course/Q/A" />
<button type="submit"> Submit </button>
</form>
<span>{basicFormat}</span>
</div>
{answerForms}
</div>
)
}
I'm very new to Javascript and I'm trying to filter/update data based on a checkbox. If you see below I can filter the data based on values in the data I created (dataset2). Dataset3 is the problem... I want to click on the checkboxes and update the dataset based on the values that are checked.
First, I'm not sure how to pass the array of values into the filter (e.g. how would I pass "Books" && "Supplies" into the filter. As you can see in dataset2 I can only get it to equal "Books". Second, how do I get it to update when checkboxes are checked/unchecked. I created a fiddle for this also. Thanks you. https://jsfiddle.net/at2046/mqjyjfox/8/
var dataset = [['Books','GEB'],
['Books','Decision Theory'],
['Supplies','Pencil'],
['Supplies','Paper']
];
document.getElementById("demo").innerHTML = dataset;
var dataset2 = dataset.filter(function (el) {
return el[0] == "Books";
});
document.getElementById("demo2").innerHTML = dataset2;
$(":checkbox").change(function() {
var dataset3 = dataset.filter(function(el) {
var checkboxes = document.getElementsByName('result');
for (var index = 0; index < checkboxes.length; index++) {
return el[0] == checkboxes[index].value;
}
});
document.getElementById("demo3").innerHTML = dataset3;
});
First, you added a $(:checkbox'), which is a jQuery syntax and you didn't have the library loaded in your fiddle.
Then, you use a return inside the for, which means that at the first iteration (choice Books) the script will exit returning only the elements belonging to the first item in the choice list.
An option is to replace the for for a while to check if the el[0] exists in any of the choices.
Lastly, you weren't checking if the checkboxes are checked, which means it would return everything no matter the state of the check box.
$(":checkbox").change(function() {
var dataset3 = dataset.filter(function(el) {
var checkboxes = document.getElementsByName('result');
var index = 0;
var found = false;
while (index < checkboxes.length && !found) {
if (checkboxes[index].checked && el[0] == checkboxes[index].value) found=true;
++index;
}
return found;
});
document.getElementById("demo3").innerHTML = dataset3;
});
https://jsfiddle.net/mqjyjfox/10/
Here I used cuisines for my checkbox items. The following code snippet gives the logic for checkboxes filtering. handleCuisineChange is the function that contains the logic. The length of for loop is 8 since the number of cuisines (the number of checkbox items) I have taken here is 8. Replace the cuisines here with your checkbox data. Apply this logic and your checkbox items are ready for filtering.
Inside axios I used my own backend API getCuisine and port number 7000.
axios I used my own backend API getCuisine and port number 7000.
handleCuisineChange=(cuisine_id)=>
{
const {cuisineArray}=this.state; //an empty array declared in constructor
if (cuisineArray.indexOf(cuisine_id) == -1)
{
cuisineArray.push(cuisine_id);
}
else
{
var index=cuisineArray.indexOf(cuisine_id);
cuisineArray.splice(index,1);
}
const {cuisineArray2}=this.state; //an empty array declared in constructor
let i=0;
for (i=0;i<8;i++)
{
if(cuisineArray[i]==undefined)
{
cuisineArray2[i]=cuisineArray[0];
}
else
{
cuisineArray2[i]=cuisineArray[i];
}
}
this.props.history.push(`/checking3?cuisine_id1=${cuisineArray2[0]}&cuisine_id2=${cuisineArray2[1]}&cuisine_id3=${cuisineArray2[2]}&cuisine_id4=${cuisineArray2[3]}&cuisine_id5=${cuisineArray2[4]}&cuisine_id6=${cuisineArray2[5]}&cuisine_id7=${cuisineArray2[6]}&cuisine_id8=${cuisineArray2[7]}`);
let filterObj={cuisine_id1:cuisineArray2[0],cuisine_id2:cuisineArray2[1],cuisine_id3:cuisineArray2[2],cuisine_id4:cuisineArray2[3],cuisine_id5:cuisineArray2[4],cuisine_id6:cuisineArray2[5],cuisine_id7:cuisineArray2[6],cuisine_id8:cuisineArray2[7]};
axios(
{
method:'POST',
url:`http://localhost:7000/getCuisine`,
headers:{'Content-Type':'application/json'},
data:filterObj
}
)
.then(res=>
{
this.setState({restaurants:res.data.restaurants});
})
.catch(err=>console.log(err))
}
render()
{
const {restaurants}=this.state;
return(
<div>
<input type="checkbox" name="cuisines" id={"1"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > North Indian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"2"} onChange={(event) => this.handleCuisineChange("2")} />
<span className="checkbox-items" > south indian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"3"} onChange={(event) => this.handleCuisineChange("3")} />
<span className="checkbox-items" > chinese </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"4"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > fast food </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"5"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Street food </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"6"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > American </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"7"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Italian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"8"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Mexican </span> <div style={{display: "block"}}> </div>
</div>
)
} //render end