Why doesn't Alert.alert() work in React native? - reactjs

https://snack.expo.io/#miralis/bad-apple
Check pressNumber. I want to Alert.alert("Nice work!") when "if" returns true, and ("Try again!") when it returns false, but Alert.alert() doesn't work.

It seems to work like #blankart said, I guess just because you declare a random num and then you can't catch the correct number each time. Just change the num to a real number like this and input it. You can go into the true statement.
PS:You could console out the num and number to check the original statement.
const [number, setNumber] = useState();
const pressNumber = () => {
const num = (Math.random() * 1).toFixed(); //random each time is different.
//if(num == number) {
if(number == 5) { // and then input 5 is the correct to nice work.
console.log("Nice work!");
Alert.alert("Nice work!")
}
else {
console.log(num) // console the num
console.log(number) // console the number
console.log("Try again!");
Alert.alert("Try again!")
}
}

Related

How to set maximum amount of decimals in react [duplicate]

This question already has an answer here:
How to limit set the maximum decimal places of a number as 8 decimal places in React using javascript
(1 answer)
Closed 8 months ago.
I created a calculator in react, but when I do some division where the result will be a repeating decimal, this result is exceeding the calculator display.
Example: 1 / 3 = 0.333333333333
Could someone help me to make the result not pass the display?
I tried to use maxLength and toFixed methods, but neither worked
Here is my code:
export default function Calculator() {
const [num, setNum] = useState(0);
const [oldnum, setOldNum] = useState(0);
const [operator, setOperator] = useState();
const [waitingForNumber, setWaitingForNumber] = useState(false);
const [shouldClearNumber, setShouldClearNumber] = useState(false);
function inputNum(event) {
const input = event.target.value;
const number = (Number(num) + Number(input))
if (number > 999999999 && !waitingForNumber) {
return;
}
if (waitingForNumber || num === 0 || shouldClearNumber) {
setNum(input);
} else {
setNum(num + input);
}
setWaitingForNumber(false);
setShouldClearNumber(false);
}
function calcular() {
if (operator === "/") {
setNum(parseFloat(oldnum) / parseFloat(num));
}
if (operator === "X") {
setNum(parseFloat(oldnum) * parseFloat(num));
}
if (operator === "-") {
setNum(parseFloat(oldnum) - parseFloat(num));
}
if (operator === "+") {
setNum(parseFloat(oldnum) + parseFloat(num));
}
setShouldClearNumber(true);
console.log("calculou!!!!");
}
}
try using setState(Number(state).toFixed(1))
https://www.w3schools.com/jsref/jsref_tofixed.asp
The accepted answer isn't a good general solution, it doesn't limit the number of decimal points, it just cuts off characters that may or may not be after the decimal.
The correct answer is using toFixed, like Mel Carlo Iguis's answer. You could call toFixed everytime before setting state:
setNum(Number(newValue.toFixed(1))) // 1 for 1 decimal place, adjust as needed
Although that method loses information-- if you want to keep num high-precision for future calculations, you can instead just use toFixed during the actual render step. This is the pattern I'd recommend:
<div> {num.toFixed(1)} </div>
You could convert the number to a string, then use slice() to trim down the number to a specified amount of digits.
And convert it back to a number for your purposes.
For example if you wanted to keep 7 digits, you could do
num.toString();
num.slice(0, 6);
Number(num)

How to create custom input field with autospaces for entering vehicle number plate

I need to devlop input field for vehicle number entry but the only problem I am facing when press backspace the logic breaks need help in this..
React.useEffect(()=>{
if(cardNumber.length===2)
setCardNumber(cardNumber+" ")
else if (cardNumber.length === 5) {
setCardNumber(cardNumber+" ")
} else if (cardNumber.length === 8) {
setCardNumber(cardNumber+" ")
}
}, [cardNumber]);
Move your logic from useEffect hook to onChange and try following:
const onChange = (event) => {
const value = event.target.value;
if ([2, 5, 8].includes(value.length)) {
setCardNumber((prev) => {
// this is only the case when we try to delete empty space
if (prev.endsWith(" ")) {
return value.slice(0, -1);
} else {
return value + " ";
}
});
} else {
setCardNumber(value);
}
};
There are many possible solutions, so this is just a one of them. Basically the idea is to read previous state and check if the value ends with an empty space.
https://codesandbox.io/s/compassionate-grass-krhwxh

React Native - Resetting setInterval duration when array.length.current == 0 or when array becomes empty

I have a function that adds numbers to an array and then plays the sounds of the numbers and then removes the numbers after they are played at an interval called 'delay'. However, I have trouble figuring out where to reset the delay back to 0. That is - when all the numbers are played and removed from the array. The whole point of this is so that the first number being added will always be played immediately (at 0 second delay), while numbers being added afterwards will be played and removed at an interval like 4 seconds. I have spent a lot of time on solving this problem, but can anyone figure out where to reset the delay back to 0 so that when the array is empty, the first number being added will always be played immediately? Remember that if you keep adding numbers, the numbers will wait at an interval like 4 seconds to being played, like a sound queue.
const [arr, setArr] = React.useState([]); //Sound queue array
const interval = React.useRef(null);
const arr_length = React.useRef(null);
const [delay, setDelay] = useState(0);
function set_remove_arr_interval(num) {
setArr((currentNumbers) => [...currentNumbers, num]);
if (!interval.current) {
interval.current = setInterval(() => {
// Sets an ongoing interval for the sound queue
console.log("Array current position: " + arr_length.current);
if (arr_length.current > 0) {
playSound(arr[0][0], arr[0][1], arr[0][2]);
setDelay(4000); //My delay duration at 4 seconds
}
if (arr_length.current === 0) {
// setDelay(0); // <-- I tried resetting the delay duration here to 0 but it resets to 0 every time a number is entered immediately and plays it, which is not what I want.
clearInterval(interval.current);
interval.current = null;
return;
}
arr_length.current = arr_length.current - 1;
setArr((currentNumbers) => [...currentNumbers.slice(1)]);
}, delay);
}
}
function add(num) {
arr_length.current = arr.length + 1;
set_remove_arr_interval(num);
}
Edit: I also tried initialising a new variable called isFirst, but it only works at alternating times of the interval:
const [isFirst, setIsFirst] = useState(true);
if (isFirst == false && arr_length.current == 0) {
setDelay(0);
setIsFirst(true);
}
if (arr_length.current > 0) {
playSound(arr[0][0], arr[0][1], arr[0][2]);
if (isFirst == true) {
setDelay(4000);
setIsFirst(false);
}
}
I now solved the problem by simply resetting the delay back to 0 using the useState hook when the array's length is at 1. Does anybody have a better solution than this? Because I believe hooks are not encouraged to be used inside functions and I also found out that sometimes console.logging them does not log the new state when changed.
sound.setOnPlaybackStatusUpdate(async (status) => {
if (status.didJustFinish === true) {
const { sound } = await Audio.Sound.createAsync(data[0], {
shouldPlay: true,
});
setSound(sound);
await sound.playAsync();
if (arr.length == 1) {
setDelay(0);
}
}
});

split a number by total number onChange input

My requirement is to split a to num in input so that it should not exceed total sum and for eg : if I enter 50 in any field other fields should have 25 each for 2 input values if there are 3 fields.
here is code sandbox for work on codesand box
Remove useEffect hook, the dependency for the hook is num and inside the callback of useEffect num is once again updated with setNum. This is a big no-no.
I suggest following changes to the handleChange callback
function handleChange(evt) {
const value = evt.target.value;
const inputElements = document
.getElementById("App")
.getElementsByTagName("input");
let numberOfInputElements = 1;
if (numberOfInputElements !== null) {
numberOfInputElements = inputElements.length - 1;
}
setNum((inputNum) => {
for (const key in inputNum) {
if (inputNum.hasOwnProperty(key)) {
inputNum[key] = value / numberOfInputElements;
}
}
return { ...inputNum, [evt.target.name]: value };
});
}
Link to codesandbox for complete code.
But I understand your requirement is slightly different from the problem statement.

Use passed parameters in for loop - React Native

I have two classes. In the first one I am fetching from an API. Then I am passing the data to the other class using props.navigation. I can display the data but I want to use those data in a For loop as in this code:
renderText = () => {
const obje = this.props.navigation.state.params.item;
Console.log(obje) //this prints correctly
for (let i = 0; i < obje.length; i++) {
console.log(obje) //this doesnt print anything
if (obje[i].name != null) {
console.log(obje}
}
}
EDIT:
When I try to print const obje, it prints. But when I try to print obje inside the for loop it doesnt, so I guess its not even going through the for loop at all.
Try this way:
renderText = () => {
const obje = this.props.navigation.state.params.item;
console.log(obje) //this prints correctly
Object.keys(obje).map((item) => {
if(item == 'name'){
console.log(obje[item])//YOU CAN PRINT NAME'S VALUE LIKE THIS
}
})
}

Resources