In my component, when I try to use substr on a string (in a object in a prop), I get the following error :
Uncaught TypeError: offer.description.subtstr is not a function
The props are passed when the Axios request is complete in the parent component. I checked and it is a string value for description.
Here is my full code :
import React, { Component } from 'react'
import {Link} from 'react-router-dom'
export class ResultBox extends Component {
render() {
var offer = this.props.offer;
var info = "| " + offer.address + " | " + offer.date;
if(offer.minimumAge > 0) {
info = info + " | Âge minimum : " + offer.minimumAge + " ans"
}
return (
<div key={offer.id} className="result-box">
<div className="result-box-img"><img src={require('../../img/user/hands.svg')} /></div>
<div>
<span className="result-box-org">{offer.organization.name}</span>
<span className="result-box-title"><Link to={"/organisme/offres/" + offer.id}>{offer.name}</Link></span>
<p className="result-box-desc">{offer.description.subtstr(0,10)}</p>
{(offer.placesAvailable > 0) ?
<span className="result-box-nPlaces">{offer.placesAvailable} places disponibles {info}</span>
:
<span className="result-box-nPlaces">{offer.placesAvailable * -1} personnes dans la file d'attente {info}</span>
}
</div>
<div className="result-box-date"></div>
</div>
)
}
}
ResultBox.defaultProps = {
offer : {description: ''}
}
export default ResultBox
```
it's substring()
https://www.w3schools.com/jsref/jsref_substring.asp
Try using
offer.description.substring(0, 10)
EDIT
you can use substr() as well..
but you have a typo in your code. What you have is subtstr()
looks like you have a typo. Should be substr not 'subtstr'
You need to destructure for that(substr) or use substring as solution already posted.
like
let offer = {
description:'Hey welcome to stack overflow'
}
const {description} = offer;
document.write(description.substr(0,10));
Related
It is about adding a code block in the next js.
def gree(name):
"""
this function greets to the person passed in as parameter
"""
print("Hello, " + name + ". Good morning!")
Code:
import React from "react";
import { CopyBlock,dracula } from "react-code-blocks";
function CodeBlockk() {
return (
<div>
<h3>GeeksforGeeks Code</h3>
<CopyBlock
text="print('GeeksforGeeks') \n dfewf"
language='python'
showLineNumbers='true'
wrapLines
theme={dracula}
/>
</div>
);
}
export default CodeBlockk;
Based on documentation showLineNumbers prop is boolean but you have entered 'true' as a string which may cause the conflict.
try this:
function CodeBlockk() {
return (
<div>
<h3>GeeksforGeeks Code</h3>
<CopyBlock
text="print('GeeksforGeeks') \n dfewf"
language='python'
showLineNumbers={true}
wrapLines
theme={dracula}
/>
</div>
);
}
export default CodeBlockk;
showLineNumbers indicates whether or not to show line numbers and data type is boolean and default value is true.
Here's the answer.
I have got the solution to my problem.
Here is the solution.
import React from "react";
import Code from "../../components/Code";
import { useEffect } from "react";
import Prism from "prismjs";
import "prismjs/themes/prism-tomorrow.css";
export default function Page(props) {
useEffect(() => {
Prism.highlightAll();
}, []);
var code1 = `var x, y, z; // Declare 3 variables
x = 5; // Assign the value 5 to x
y = 6; // Assign the value 6 to y
z = x + y; // Assign the sum of x and y to z
document.getElementById("demo").innerHTML =
"The value of z is " + z + ".";`;
var code2 = `print("Hello world")
print("Hello world")`;
return (
<div className="flex justify-center">
<main className="max-w-2xl lg:w-[800px] sm:w-[800px] w-72">
<pre className="line-numbers">
<code className="language-jsx">{code1}</code>
</pre>
<pre className="line-numbers">
<code className="language-jsx">{code2}</code>
</pre>
</main>
</div>
);
}
So I have this function here:
const printCardList = (arr) => {
const uo_list = document.getElementById("verify_list");
arr.forEach((card) => {
let list_item = document.createElement("LI");
let str = card.name + " " + card.mana_cost + " " + card.set_name;
list_item.appendChild(document.createTextNode(str));
uo_list.appendChild(list_item);
});
};
and its suppose to insert list items into and unorder list from an array of card objects.
return(
<div className="list-confirm">
<h3> Please confirm card list </h3>
<ul id="verify_list"></ul>
<br />
<button onClick={getCardList}>Confirm</button>
</div>
);
If I do a console.log on arr I can verify that it is an array of cards, but if I console.log card from inside the for each it does not even trigger. It's like the for each does not run. Does anyone have an idea why this is happening?
I'm not sure what you are trying to do, the first part of your code is plain javascript that manipulates the DOM, while the second part is react js object.
You normally don't want to mix these two, either you code your javascript as part of the html, like the first part, or - if you want to create an array of cards in react you can do something like:
let cardList = arr.map(card => {
listItem = <li>{card.name + " " + card.mana_cost + " " + card.set_name }</li>
return listItem;
})
return(
<div className="list-confirm">
<h3> Please confirm card list </h3>
<ul id="verify_list">{cardList}</ul>
<br />
<button onClick={getCardList}>Confirm</button>
</div>
);
what I did is assigned the list itself to a variable named 'cardList', JSX object are just javascript objects, so you can assign them to a variable or return then from a function.
to place the card list inside the page (or component), you can just use the {} notation, which will embed the cardList object as part of the returned JSX object.
Thanks for all the advice. In hindsight, I should have stuck to what I was learning and not try to freestyle. React is about using states. So rather than having a function that will generate HTML from an array of data and I had to do use "the state". Then code the render to loop through the list of cards when the button is pressed.
const [state, setState] = useState([]);
const card_list= ()=> {...}
const changeState = ()=> {setState(card_list)}
return(
<div className="list-confirm">
<h3> Please confirm card list </h3>
<ul>
{state.map((card) => (
<li>{card.name}</li>
))}
</ul>
<br />
<button onClick={changeSate}>Confirm</button>
</div>
);
You should change the onClick. More precisely call the method after getting items from getCardList() method.
This is an example:
const printCardList = (arr) => {
const uo_list = document.getElementById("verify_list");
arr.forEach((card) => {
let list_item = document.createElement("li");
let str = card.name + " " + card.mana_cost + " " + card.set_name;
list_item.appendChild(document.createTextNode(str));
uo_list.appendChild(list_item);
});
};
// this is a test method. Not the real one
const getCardList = () => {
return [ { name: "Card", mana_cost: 0, set_name: "Set: Card" } ];
};
<div className="list-confirm">
<h3> Please confirm card list </h3>
<ul id="verify_list"></ul>
<br />
<button onClick="printCardList(getCardList())">Confirm</button>
</div>
Is there a possibility to set singe value on React rc-slider Range component? At present to do that I need to drag the second handle in front of the first one or the first one drag after the second one and this behavior is allowing user to drag the handle behind the rail if we are on the edge values
I would like to set this up like on the third image it would show from eg. 39 to 39. Here is my code
import React, { useState } from "react";
import Slider, { Range } from "rc-slider";
import "rc-slider/assets/index.css";
export const RangeSlider = ({
min,
max,
error,
displayUnit,
stereo,
onChange
}) => {
const [minVal, setMinVal] = useState(min);
const [maxVal, setMaxVal] = useState(max);
const props = {
onChange: value => {
if (stereo) {
setMinVal(value[0]);
setMaxVal(value[1]);
} else {
setMinVal(value);
setMaxVal(value);
}
onChange(value);
},
min: min,
max: max,
defaultValue: stereo ? [0, 100] : 0
};
return (
<>
{error && (
<span className="position-outside">
<i className="fas fa-exclamation-circle fa text-danger mt-2"></i>
</span>
)}
<div className="text-primary h6 mb-3">
<strong>
{stereo &&
`Od ${minVal}${
displayUnit ? " " + displayUnit : ""
} do ${maxVal}${displayUnit ? " " + displayUnit : ""}`}
{!stereo &&
`${minVal}${displayUnit ? " " + displayUnit : ""}`}
</strong>
</div>
{stereo ? <Range {...props} /> : <Slider {...props} />}
</>
);
};
I am aware that single range slider is for single values, although the client has requested this feature.
Thanks
Firstly my apologies for making a confusion with the title and a question, the title should be different, I have found the bug I thought it was rc-slider, however it was me translating the second rail to be contained within the track, I have explained everything in detail in this post styling rc-slider track to contain handles within itself therefore I am closing this one. Thanks
I have set up a conditional element on click on a button I've made within react. but default prop runs onload without clicking the button how can I fix this issue?
the button looks like this:
<p onClick={Butter + Milk + Bread + Soup + Cheese > 0 ? props.next_ClickHandler : alert('Please Input some food!')}>Buy Now!</p>
I would like it so that if the values add to greater than 0 the props are passed but if not an alert is played why it this not working as intended?
Edit full code:
import React, { useState, useEffect, useContext } from "react";
import Data from '../shoppingData/Ingredients';
import { quantitiesContext } from '../shoppingData/Quantities';
const ShoppingPageOne = (props) => {
//element displays
const [pageone_show, setPageone_show] = useState("pageOne");
//stores quantities of items as JSON objects
const [Quantities, setQuantities] = useContext(quantitiesContext);
const quantities = useContext(quantitiesContext);
const Bread = quantities[0].Bread.quantities;
const Milk = quantities[0].Milk.quantities;
const Cheese = quantities[0].Cheese.quantities;
const Soup = quantities[0].Soup.quantities;
const Butter = quantities[0].Butter.quantities;
useEffect(() => {
//sets info text using Json
if (props.showOne) {
setPageone_show("pageOne");
} else {
setPageone_show("pageOne hide");
}
}, [props.showOne]);
return (
<div className={"Shopping_Content " + pageone_show}>
<div className="Shopping_input_aligner">
<div className='Shopping_input_container'>
{Data.map((Ingredients) => {
//updates Quanties Hook
const handleChange = (event) => {
setQuantities({
...Quantities,
[Ingredients.Name]: {
...(Quantities[Ingredients.Name] ?? {}),
quantities: event.target.value
}
});
};
return (<div className={"Shopping_input " + Ingredients.Name} key={Ingredients.Name}>
<p>{Ingredients.Name} £{Ingredients.Price}</p>
<input onChange={handleChange.bind(this)} min="0" placeholder="Input food quantity" type="number"></input>
</div>)
})}
</div>
<div className='Discount_list'>
<h3>Discounts:</h3>
<li>Buy one cheese get one free!</li>
<li>Buy a Soup get a half price bread!</li>
<li>A third off butter!</li>
</div>
</div>
<div className="Shopping_Buttons">
<p onClick={() => {Butter + Milk + Bread + Soup + Cheese > 0 ? props.next_ClickHandler : alert('Please Input some food!')}} >Buy Now!</p>
</div>
</div>
);
};
export default ShoppingPageOne;
You can have a cleaner code with something like this if you're using React Hooks
const [ingredientsGreaterThanZero, setIngredientsGreaterThanZero] = useState(false);
useEffect(() => {
if (butter + milk + bread + soup + cheese > 0) {
setIngredientsGreaterThanZero(true)
} else {
setIngredientsGreaterThanZero(false)
}
}, [butter, milk, bread, soup, cheese]);
...
{ingredientsGreaterThanZero ?
<p onClick={props.next_ClickHandler}>Buy Now!</p> :
<p onClick={() => alert('Please Input some food!')}>Buy Now!</p>
}
<p onClick={() => { Butter + Milk + Bread + Soup + Cheese > 0 ? props.next_ClickHandler : alert('Please Input some food!')}}>Buy Now!</p>
Can you try using this?
Reason
If you attach any event in element with onClick() or any other event handler,
You shouldn't add any function invocation like in your example alert().
Because, of parentheses () the function runs when component mounted in dom.
Example:
<p onClick={alert('runs on load')}>wrong way</p>
Solution
You have to add an empty function and and writes your codes in it. If your codes contain function invocation ( with parentheses () ).
Example:
<p onClick={() => alert ('only runs on click')}>right way</p>
Happy Coding :)
I am trying to make a search that highlights the matching characters within the displayed list.
I having trouble figuring out how I can add a DOM node within a list as it is being created/updated. The following code is where I got to. I think I understand why its not working (i keep getting 'Stephine Ma[object Object]ks'as the output). I am fairly sure I need to add it as an actual DOM node using .HTMl or .innerHTML but with react im not sure how one would do that.
import React from 'react';
import { Router, Route, Link } from 'react-router';
export default class extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
var divImage = {
backgroundImage : "url(" + this.props.image + ")"
};
var test = this.props.name;
if(this.props.name.indexOf(this.props.filterText) != -1 ) {
var pattern = this.props.filterText.toString();
test = test.replace(pattern, <span className="highlight">+pattern+</span>)
}
return (
<li className="panelItem">
<a className="item-title" style={divImage}>{test}</a>
</li>
);
}
}
Here is an example if you can use indexOf instead of regex matching. Builds all the nodes and wraps them in spans.
https://jsfiddle.net/2zx84koy/
var Hello = React.createClass({
render: function() {
var name = this.props.name;
var startIdx = name.indexOf(this.props.filterText);
var textNodes = <span>{name}</span>
if(startIdx > -1 ) {
textNodes = (
<span>
{name.substring(0, startIdx)}
<span className="highlight">{name.substring(startIdx, startIdx + this.props.filterText.length)}</span>
{name.substring(startIdx + this.props.filterText.length)}
</span>
)
}
return (
<li className="panelItem">
<a className="item-title">{textNodes}</a>
</li>
);
}
});
You can do innerHTML in react but in general its not advised unless you know for sure it would not leave you vulnerable to xss attacks. I put an example below of how to convert your code to that style just for reference.
var test = this.props.name;
if(this.props.name.indexOf(this.props.filterText) != -1 ) {
var pattern = this.props.filterText.toString();
test = test.replace(pattern, '<span class="highlight">' + pattern + '</span>')
}
return (
<li className="panelItem">
<a className="item-title" dangerouslySetInnerHTML={{__html: test}}></a>
</li>
);
I was working on something similar quite recently, I created a library (prelude-extension) and a component (react-selectize) for it, here's a demo, maybe it is what you are looking for.