Passing props to Field validate gives previous props values - reactjs

Passing props to Field validate gives previous props values, especially in this case the Quantity. Using this sandbox, follow these steps:
Open sandbox then console
Set Value to 2
Select Quantity to 2
From console, quantity is still set to 1
Press Submit
Pop up has correct values {"amount":4,"quantity":"2","value":"2"}
Change Value to 1 (Now in Console Quantity is 2)
Error message appears
Instead, what should happen:
Step 4 & 7 should have correct Quantity. props has previous value, not updated
Step 8 should not have error because 1 * 2 = 2
Field validation should have current props values
I followed this issue to handle passing props to validate function, but it seems whenever the props changed the component did not get updated and instead will have the previous value.

This one is works for me.
Replace this code with your validateAmount function.
validateAmount = (amount, e) => {
//const { value, quantity } = this.props.formValues
console.log('amount:', amount, 'value:', e.value, 'quantity:', e.quantity)
if (amount < e.value * e.quantity) return 'Nope!'
}
Here second parameter gets the current state of form values. First answer was taken the Redux State.

try this one
validateAmount = (amount) => {
//const { value, quantity } = this.props.formValues
// instead for using values from props ,get values from current state
const { value, quantity } = store.getState().form.simple.values;
console.log('amount:', amount, 'value:', value, 'quantity:', quantity)
if (amount < value * quantity) return 'Nope!'
}

Related

I'm trying to update the row values in MUI datagrid, i'm using processRowUpdate property.But, I'm only getting recent updated cell value only

Here **Skills ** will have the array of objects which includes the values Which I'm updating.
const handleProcessRowUpdate = (newRow, oldRow) => {
console.log("update called", newRow, oldRow);
let skills = assignedskillList;
let result = skills.map((item) => {
if (item.skill_id == params.skill_id) {
console.log("ids", params.skill_id, item.skill_id);
if (item.skill_level !== newRow.skill_level) {
item.skill_level = newRow.skill_level;
}
if ((item.target_level = newRow.target_level)) {
item.target_level = newRow.target_level;
}
console.log("idsss", item.skill_level, item.target_level); // here for first column edit //I'm getting current edited value only, for the second col edit getting only second column //value.the first value is resetting
}
setUpdatedVal(result); //I'm setting this in a new array to use this for post to API
return item;
});
tried onCellEdit commit , but, thats not worked. any other solutions ?
or correct me if I'm setting the value wrongly.
Thanks In advance.....
Finally, I found it.
Hope it might be helpful for someone in future
instead of updating the value inside the map. I've just defined a result array outside and assigned the map to that, Now I can get all updated values..
Thank you...

why setState only updates on mutating original state

interface list {
name: string,
id: number,
marks: number
}
component state :
{
listOfStudents: list[],
}
now on some event, where marks is modified for a student with given name and following handler function, the following doesn't work
currentList = this.state.listOfStudents;
//find the list object with the given name
listToModify = currentList.map(item, ....=> item.name === event.name);
// update its marks
listToModify.marks = event.marks;
//set new state
this.setState({listOfStudents: currentList});
But the following works:
//get a copy of the object
currentList = [...this.state.listOfStudents];
//find the list object with the given name
listToModify = currentList.map(item, ....=> item.name === event.name);
// update its marks
listToModify.marks = event.marks;
//set new state
this.setState({listOfStudents: currentList});
I didn't have to add new data but modify an existing one, why is mutation required in such a case?
for a given state that is an object or array, react uses only its reference to compare and decide if it will update state, it doesn't do deep comparision between objects values.
the first case you are passing the same reference, therefore there is no update state. actually, if you modify the array at first example, that's actually mutating state directly.
second case you are cloning into a new fresh array, which holds a different reference. since the reference is different from previous array, react now update its state. that's actually the right approach to update state when dealing with arrays/objects.

How to pass a parameter from a different source into ListItem of the Flatlist?

I am rendering some items in the Flatlist where I call the renderNativeItem to render them in a ListItem and like usual I pass the values as parameter, however, I want to pass a value to subtitle from a different array.
The reason behind this is that in the ìtt parameter there are values of a users such as name, surname but in calculated_distances there are values calculated seperately in another function but which were fetched together from the same document in database.
So, when fetching from db, I set all the data to this.state.dataSource array, then I take location from that array and make a calculation and set it to this.state.calculated_distances. After this is done then I call Flatlist to render the this.state.dataSource, but the calculated distance for each user is in another array in this.state.calculated_distances.
This is basically how I ended up in this situation.
Here is the renderNativeItem function:
renderNativeItem = (itt) => {
const { calculated_distances } = this.state;
return (
<ListItem
title={itt.name + " " + itt.surname}
subtitle={calculated_distances}
/>
)
}
Set
subtitle={functionName(itt.id)}
so that
functionName gets calculated_distances with id or another value

How to use Group by query in laravel?

this is how the data is displayed but i want
Rhugveda desai -> flowers,Sarees,Prasad
In my application i need to use group by clause . But i am getting a syntax error.Also, What should i do if i want quantity column to be multiplied by amount to get the total? My tables are inkind and inkind_items, where inkind.id is foreign key in inkind_items table as inkind_id.
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #11
of SELECT list is not in GROUP BY clause and contains nonaggregated
column
my inkind_items tabel is inkind_items
my inkind table is inkind
My query is:
$inkinds = DB::table('inkind')
->join('inkind_items', 'inkind.id', '=', 'inkind_items.inkind_id')
->select('inkind.*', 'inkind_items.*')
->groupBy('inkind_items.inkind_id')
->get();
Try using group_concat()
$inkinds = DB::table('inkind')
->join('inkind_items', 'inkind.id', '=', 'inkind_items.inkind_id')
->select('inkind.*', DB::raw('group_concat(inkind_items.name) as items'))
->groupBy('inkind_items.inkind_id')
->get();
Here I'm assuming inkind have field name and inkind_items has fields items.
You can use Laravel collection methods for that.
Just call:
$inkinds->groupBy('inkind_id');
after ->get(). Considering that inkind_id is unique column for both tables
Hi. You asked another question earlier today (about displaying an input when a particular checkbox is checked) but deleted it before I submitted my answer, so I thought I would paste the answer here instead:
Just to get you started, here is an explanation of how to use
addEventListener and createElement to achieve your desired result.
If any part of it is still unclear after studying the code and the
accompanying comments, please search for the name of the still-unclear function on
MDN.
(For example, https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName.)
// Sets `box1` to refer to the first element on the page with the class "box".
const box1 = document.getElementsByClassName("box")[0];
// Sets `container` to be the element whose id attribute has the value "container".
// (This is where our new input element, inside a new label element, will be added.)
const container = document.getElementById("container");
// Begins listening for clicks. From now on, whenever the user clicks anywhere
// on the page, our listener will call the `noticeClick` function.
document.addEventListener("click", noticeClick);
function noticeClick(event){
// Because this function's name is the second argument in
// the call to `document.addEventListener`, above, it is
// automatically called every time a 'click' event happens on the
// page (and it automatically receives that event as an argument.)
// The "target" of the event is whatever the user clicked on.
// So we set the variable `targ` to refer to this target, and we check whether:
// 1) the clicked target is our checkbox,
// 2) this click caused the checkbox to gain the "checked" attribute, and
// 3) we have not already given the checkbox the "added" class
const targ = event.target;
if(targ.id == "box1" && targ.checked && !targ.classList.contains("added")){
// If all three conditions are met, we...
// ...set two variables, `label` and `val`
const label = event.target.id;
const val = event.target.value;
// ...call the `createInput` function, passing these variables as its two arguments
createInput(label, val);
// ...give the checkbox the "added" class (so we can avoid accidentally adding it again)
targ.classList.add("added");
}
}
function createInput(newLabel, newValue){
// When the user has checked our checkbox, the `noticeClick` function
// will call this function, which receives two arguments (which we can
// see, by examining the `noticeClick` function, are two strings: the
// `id` attribute of box1 and the `value` attribute of box1.)
// We use `document.creatElement` to create an `input` element and a
// `label` element, and `document.createTextNode` to set some text
// to be used in the label (using the "newLabel" argument.)
const myInput = document.createElement("input");
const myLabel = document.createElement("label");
const myLabelText = document.createTextNode(newLabel + " ");
// We set our new `input` element's value using the "newValue" argument.
myInput.value = newValue;
// We use `appendChild` to put both the text and the input element
// inside the label, and to put the label inside `container`.
myLabel.appendChild(myLabelText);
myLabel.appendChild(myInput);
container.appendChild(myLabel);
}
// This process can be applied to multiple checkboxes on the same page
// by adding a loop inside the `noticeClick` function, where the string
// "box1" should be replaced with a variable that can refer to the id of a
// different checkbox's `id` for each iteration of the loop.
<label>
<input type="checkbox" id="box1" class="box" value="value1" />
Label for box1
</label>
<hr />
<div id="container"></div>

App returns false as value instead of number

I'm making a shopping cart application with react on the front end, redux for state management and firebase on the back end. The app is set up so you have to be logged in, in order to shop so each cart is specific to a uid that firebase provides with its authentication system.
This is the structure that I have to account for item quantity:
It takes the path of users/uid/cart. The logic is that on item add, I push the items id to the ids array, and set the quantity to be that of the item quantity in the cart. The quantity structure looks like this:
quantity: {
1 (item id): 2 (quantity)
}
But as you can see in the snippet, when there is no items added to the cart, the quantity gets set to false instead of an integer. However, on the second add, it works as it's supposed to but it doesn't reflect the previous add to the cart. So if I initially added 2 and then added 1 after that, it would total the quantity to 1 when it should be 3.
database
.ref(`users/${uid}/cart/quantity`)
.transaction(data => {
return data != null && {
...data,
[item.id]: value
}
})
Above is my add to cart quantity action
case ADD_TO_CART:
return {
...state,
ids: [...state.ids, action.payload.id],
quantity: {
...state.quantity,
[action.payload.id]: state.quantity[action.payload.id] + action.payload.value
}
}
Above is my add to cart reducer
The first time a transaction handler function executes, you can expect it to receive a null value. Your code needs to handle this. Subsequent invocations of the handler function will receive the current value from the database.
In your particular case when your transaction handler receives a null value, it returns null, since data != null evaluates false, and the next boolean AND is short-circuited. You need to do something different in the initial case that data is null, perhaps write a quantity of 0.

Resources