Conditional statement in react-native - javascript

I need a helping hand. I got a little lost in my code to set up a condition.
Basically I want to set up a checkbox that will look for the stock of a product. My array of product information is stored in this.state.displayArray.
If the product is in stock, so if this.state.displayArray.stock> 0 the checkbox is checked.
actually it sounds simple like that and i think it is but i need a little helping hand to make sure i do it right, I don't know where to add the condition, in the function or directly in the checkbox.
Thanks for your help.
export default class Stock extends Component {
constructor(props) {
super(props);
this.state = {
stock : true,
}
};
initListData = async () => {
let list = await getProducts(1);
if (list) {
this.setState({
displayArray: list,
loadMoreVisible: (list.length >= 15 ? true : false),
currentPage: 2
});
console.log(this.state.displayArray)
}
};
async UNSAFE_componentWillMount() {
this.initListData();
console.log(this.state.displayArray)
}
render() {
return (
<View style={styles.container}>
<View pointerEvents="none" style={{ flexDirection: 'row', alignItems:'center', justifyContent:'center'}}>
<CheckBox
value={this.state.stock}
/>
<Text style={{marginTop: 5}}>Stock</Text>
</View>
</View>
);
}
}
displayArray: (for now it's a flight but it will change, I have someone working on API)
Array [ Object {
"cost": 0,
"created_at": "2020-12-14T15:54:50Z",
"custom_fields": Object {
"_161_": "4137",
"_162_": "48",
"_163_": "10926",
"_164_": "0",
"_165_": "FLY",
"_166_": "2020-12-14T14:54:37.737Z",
"_167_": "2020-12-31T14:54:37.737Z",
"_168_": "0",
"_171_": "0",
"_300_": "412:00",
"_301_": "45.725556|5.081111",
"_302_": "-27.7078990936|-67.0951004028",
"_303_": "Lyon Saint-Exupéry Airport",
"_304_": "Londres/Belén Airport",
"_310_": "60",
},
"description": "",
"family_id": 0,
"id": 1061,
"incl_tax": 0,
"is_visible": 1,
"name": "Lyon Saint-Exupéry Airport (14/12/2020 à 15:54) > Londres/Belén Airport (31/12/2020 à 15:54)",
"photo": "",
"quantity": 0,
"reference": "",
"stock_status": "1",
"tax_rate_id": 0,
"unit": "",
"updated_at": "2020-12-14T15:54:50Z",
"weight": 0, }, Object {
"cost": 0,
"created_at": "2020-11-15T01:38:08Z",
"custom_fields": Object {
"_161_": "1373",
"_162_": "30",
"_163_": "4680",
"_164_": "0",
"_165_": "FLY",
"_166_": "2020-11-21T00:37:00.000Z",
"_167_": "2020-11-29T00:37:00.000Z",
"_168_": "0",
"_171_": "0",
"_300_": "190:00",
"_301_": "43.6539083949|-79.65785399079999",
"_302_": "-22.285699844399996|-62.7136993408",
"_303_": "Tarten Heliport",
"_304_": "Santa Victoria Airport",
"_310_": "-480",
},
"description": "",
"family_id": 0,
"id": 896,
"incl_tax": 0,
"is_visible": 1,
"name": "Tarten Heliport (2020-11-21 at 16:37) > Santa Victoria Airport (2020-11-29 at 16:37)",
"photo": "",
"quantity": 0,
"reference": "",
"stock_status": "1",
"tax_rate_id": 0,
"unit": "FLY",
"updated_at": "2020-11-15T01:38:08Z",
"weight": 0, }, ]

Related

Can console log fetched array but cant get the values

So I can call the variable "teams" and see the data fine but I can't get the values from it in my {#each} block. I know its not part of the "fixtures" variable I'm iterating through and tbh that's probably the issue.
Does anyone know how I can get the actual values within "teams" instead of getting 'undefined' or a better way of fetching multiple arrays within themselves? (ill put the example at the bottom)
my +page.svelte
<script>
export let data;
const { fixtures } = data;
const teams = fixtures.flatMap(fixtures => fixtures.participants)
console.log(teams)
</script>
<div class="flex flex-col absolute top-[0] right-0 w-[85vw] p-6">
<div class="">
{#each fixtures as fixture}
<p>{fixture.name}</p>
<div class="">{fixture.home_score}{fixture.away_score}</div>
<p>{teams.short_code}</p>
{/each}
</div>
</div>
+page.server.js
export const load = async () => {
const fetchList= async () => {
const url = `https://api.sportmonks.com/v3/football/schedules/seasons/19734?api_token=${process.env.API_KEY}`;
const res = await fetch(url);
const data = await res.json()
return data.data.flatMap(data => data.rounds.map(rounds => rounds.fixtures)).flat()
}
return {
fixtures: fetchList(),
}
}
The API
{
"data": [
{
"id": 77457864,
"sport_id": 1,
"league_id": 8,
"season_id": 19734,
"type_id": 223,
"name": "Regular Season",
"sort_order": 1,
"finished": false,
"is_current": true,
"starting_at": "2022-08-05",
"ending_at": "2023-05-28",
"rounds": [
{
"id": 274668,
"sport_id": 1,
"league_id": 8,
"season_id": 19734,
"stage_id": 77457864,
"name": "1",
"finished": true,
"is_current": false,
"starting_at": "2022-08-05",
"ending_at": "2022-08-07",
"fixtures": [
{
"id": 18535049,
"sport_id": 1,
"league_id": 8,
"season_id": 19734,
"stage_id": 77457864,
"group_id": null,
"aggregate_id": null,
"round_id": 274668,
"state_id": 5,
"venue_id": 206,
"name": "Manchester United vs Brighton & Hove Albion",
"home_score": 1,
"away_score": 2,
"starting_at": "2022-08-07 13:00:00",
"result_info": "Brighton & Hove Albion won after full-time.",
"leg": "1/1",
"details": null,
"length": 90,
"placeholder": false,
"last_processed_at": "2022-12-05 09:15:37",
"starting_at_timestamp": 1659877200,
"participants": [
{
"id": 14,
"sport_id": 1,
"country_id": 462,
"venue_id": 206,
"gender": "male",
"name": "Manchester United",
"short_code": "MUN",
"image_path": "https://cdn.sportmonks.com/images/soccer/teams/14/14.png",
"founded": 1878,
"type": "domestic",
"placeholder": false,
"last_played_at": "2022-12-10 17:00:00",
"meta": {
"location": "home"
}
},
{
"id": 78,
"sport_id": 1,
"country_id": 462,
"venue_id": 480,
"gender": "male",
"name": "Brighton & Hove Albion",
"short_code": "BRH",
"image_path": "https://cdn.sportmonks.com/images/soccer/teams/14/78.png",
"founded": 1901,
"type": "domestic",
"placeholder": false,
"last_played_at": "2022-12-08 13:00:00",
"meta": {
"location": "away"
}
}
]
},
There's a "dirty" way to do it with {#key}

How to Destructure JSON array>object>array

I'm trying to destructure a JSON file that looks like this:
[
{
"Bags": [
{
"id": 1,
"name": "Michael Kors Bag",
"price": 235,
"imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
},
{
"id": 2,
"name": "Ted Baker Bag",
"price": 495,
"imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
},
{
"id": 3,
"name": "Coach Bag",
"price": 238,
"imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
},
{
"id": 4,
"name": "Kate Spade Bag",
"price": 35,
"imgURL": "/imgs/10.jpg"
}
]
},
{
"Shoes": [
{
"id": 1,
"name": "Michael Kors Bag",
"price": 235,
"imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
},
{
"id": 2,
"name": "Ted Baker Bag",
"price": 495,
"imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
},
{
"id": 3,
"name": "Coach Bag",
"price": 238,
"imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
},
{
"id": 4,
"name": "Kate Spade Bag",
"price": 35,
"imgURL": "/imgs/10.jpg"
}
]
}
]
So that I get the name of the objects ("Bags" and "Shoes").
I'm trying to print out the results on a page based on which is which and I'm feeding in the names as strings to a Store component like so:
<Route path="/store" element={<Store merch="Bags" />} />
This is my Store.tsx file, it doesn't work at all but it's my attempt:
import storeItems from "../data/items.json";
import { Row, Col, Container } from "react-bootstrap";
import { StoreItem } from "../components/StoreItem";
import { useState } from "react";
type StoreProps = {
merch: string;
};
export function Store({ merch }: StoreProps) {
const [data, setData] = useState([]);
for (let i = 0; i < storeItems.length; i++) {
let a = Object.values(storeItems[i]);
console.log(a);
}
console.log(storeItems);
return (
<>
<Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
<h1 className="m-5">Bags</h1>
<Row md={2} xs={1} lg={3} className="g-3">
{storeItems.map((item) => (
<Col>
<StoreItem key={item.id} {...item} />
</Col>
))}
</Row>
</Container>
</>
);
}
In order to get ["Bags", "Shoes"] from your storeItems you could:
const names = storeItems.flatMap(mi => Object.keys(mi));
This would get additional keys on the same object as well, so if you had:
const storeItems = [
{ "Bags": /*...*/{}, "Bags2": /*...*/{}, },
{ "Shoes": /*...*/{} },
];
then it would return [ "Bags", "Bags2", "Shoes" ]
I have to say, your data is in a pretty strange format, but I answered the question exactly as written
Also, if you want the names of all of the objects in a list, as in the name property of each object you could do something like:
const names = storeItems.flatMap(storeItem =>
Object
.values(storeItem)
.flatMap(itemList => itemList.map(item => item.name))
);
Also, if you want the names of all of the objects in the keys of an object by the name (like "Bags", or "Shoes") then you could:
const names = Object.fromEntries(storeItems.flatMap(storeItem =>
Object.entries(storeItem)
).map([k,v] => [k,v.map(i => i.name)]))
I'm not quite sure which one of these you wanted, so I included all of them (:
Edit
Looking at your code it seems as if you want to get a specific section of the data. This could be done by something like this:
const name = "Shoes";
const items = storeItems.flatMap(si => Object.entries(si))[name]
or if you know that your data is going to always have shoes first and be in the exact format then you could just do
const name = "Shoes";
const items = storeItems[1]["Shoes"];
Is this what you're trying to do?
const products = [
{
"Bags": [
{
"id": 1,
"name": "Michael Kors Bag",
"price": 235,
"imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
},
{
"id": 2,
"name": "Ted Baker Bag",
"price": 495,
"imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
},
{
"id": 3,
"name": "Coach Bag",
"price": 238,
"imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
},
{
"id": 4,
"name": "Kate Spade Bag",
"price": 35,
"imgURL": "/imgs/10.jpg"
}
]
},
{
"Shoes": [
{
"id": 1,
"name": "Michael Kors Bag",
"price": 235,
"imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
},
{
"id": 2,
"name": "Ted Baker Bag",
"price": 495,
"imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
},
{
"id": 3,
"name": "Coach Bag",
"price": 238,
"imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
},
{
"id": 4,
"name": "Kate Spade Bag",
"price": 35,
"imgURL": "/imgs/10.jpg"
}
]
}
]
const getProductsByKey = key => products
.filter(product => product.hasOwnProperty([key]))
.flatMap(obj => obj[key])
console.log(getProductsByKey('Shoes'))
The output of the above code would be:
[
{
id: 1,
name: 'Michael Kors Bag',
price: 235,
imgURL: '/imgs/03045643da82a42a4a5c86842f4b17f1.jpg'
},
{
id: 2,
name: 'Ted Baker Bag',
price: 495,
imgURL: '/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg'
},
{
id: 3,
name: 'Coach Bag',
price: 238,
imgURL: '/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg'
},
{ id: 4, name: 'Kate Spade Bag', price: 35, imgURL: '/imgs/10.jpg' }
]
Please note that the supplied data is incorrect as the items under the key "Shoes" are apparently bags.
I'll explain the why and how of my code. First off, I wanted to make a function that could take any key as an argument. Today we have 'Bags' and 'Shoes', but tomorrow we may have more keys. Therefore, I didn't want to propose a solution that would involve "hard-coded" keys.
Once we have the key, we can use Array.prototype.filter to find the object containing the items we want. In the data we are provided with, 'Bags' and 'Shoes' are keys, not values. Hence why I used product.hasOwnProperty([key]) in the callbackFn. Note the use of the square brackets as we are searching for the value of a dynamic variable named key, not the actual string 'key'. Next we use Array.protoype.flatMap to get to the part of each object that we want, which is the array of items. We use .flapMap here to avoid the nested array that would normally result by chaining filter and map to the data.
For getting the shoes you can use this:
storeItems[1]["shoes"]
And for getting the bags you can use this:
storeItems[0]["bags"]
So, in the return expression in your attempt code, instead of this:
return (
<>
<Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
<h1 className="m-5">Bags</h1>
<Row md={2} xs={1} lg={3} className="g-3">
{storeItems.map((item) => (
<Col>
<StoreItem key={item.id} {...item} />
</Col>
))}
</Row>
</Container>
</>);
use this (for bags):
return (
<>
<Container className="mw-80 d-flex align-items-center justify-content-center p-0 flex-column mb-5">
<h1 className="m-5">Bags</h1>
<Row md={2} xs={1} lg={3} className="g-3">
{storeItems[0]["bags"].map((item) => (
<Col>
<StoreItem key={item.id} {...item} />
</Col>
))}
</Row>
</Container>
</>);
You can use:
a combination of Array.map and Object.keys to get an array with available categories from storeItems object
Array.find to get the products for a given merch category.
const storeItems = [
{
"Bags": [
{
"id": 1,
"name": "Michael Kors Bag",
"price": 235,
"imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
},
{
"id": 2,
"name": "Ted Baker Bag",
"price": 495,
"imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
},
{
"id": 3,
"name": "Coach Bag",
"price": 238,
"imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
},
{
"id": 4,
"name": "Kate Spade Bag",
"price": 35,
"imgURL": "/imgs/10.jpg"
}
]
},
{
"Shoes": [
{
"id": 1,
"name": "Michael Kors Bag",
"price": 235,
"imgURL": "/imgs/03045643da82a42a4a5c86842f4b17f1.jpg"
},
{
"id": 2,
"name": "Ted Baker Bag",
"price": 495,
"imgURL": "/imgs/4c176b2fa86bdcddf74822c2501bbcac.jpg"
},
{
"id": 3,
"name": "Coach Bag",
"price": 238,
"imgURL": "/imgs/coach-jes-crossbody-signature-canvas-brown-black-59181.jpg"
},
{
"id": 4,
"name": "Kate Spade Bag",
"price": 35,
"imgURL": "/imgs/10.jpg"
}
]
}
]
// Get the values for merch types
const categories = storeItems.map((entry) => Object.keys(entry)[0])
console.log(categories)
// Find the products for a given merch
const merch = 'Shoes'
const products = storeItems.find((entry) => entry[merch])[merch]
console.log(products)

Selection of product options as a combination of options

I am trying to achieve the following for my project.
combinations
my data structure for options and combinations as following:
"options": [
{
"id": "96ce60e9-b09b-4cf6-aeca-83f75af9ef4b",
"position": 0,
"name": "Color",
"values": [
{
"id": "9056c8d4-a950-43bc-9477-283a8954285b",
"name": "",
"label": "RED"
},
{
"id": "35c7cc36-2ff4-4eb6-bc96-03cc3ea04751",
"name": "",
"label": "BLACK"
}
]
},
{
"id": "c657ee5b-57bb-4265-8113-4fefca71f785",
"position": 1,
"type": "",
"name": "SIZE",
"values": [
{
"id": "494196ec-5857-48b1-be35-ffc785e5020d",
"name": "",
"label": "LARGE"
},
{
"id": "389255cb-0c88-45e8-a1dc-6ce9fedbd98c",
"name": "",
"label": "SMALL"
}
]
}
],
Variants:
"combinations": [
{
"id": "84468215-d6b5-455e-bfdc-6a03cfe49d21",
"ids": [
"9056c8d4-a950-43bc-9477-283a8954285b",
"494196ec-5857-48b1-be35-ffc785e5020d"
],
"quantity": "12",
"code": 0,
"barcode": 0,
"sellPrice": 0
},
{
"id": "4c84ec32-bf4c-463d-9872-bc6a9794e7ba",
"ids": [
"9056c8d4-a950-43bc-9477-283a8954285b",
"389255cb-0c88-45e8-a1dc-6ce9fedbd98c"
],
"quantity": "12",
"code": 0,
"barcode": 0,
"sellPrice": 0
},
{
"id": "76a3ccdd-c8b4-44dc-99bf-a83a65dc0fe0",
"ids": [
"35c7cc36-2ff4-4eb6-bc96-03cc3ea04751",
"494196ec-5857-48b1-be35-ffc785e5020d"
],
"quantity": 0,
"code": 0,
"barcode": 0,
"sellPrice": 0
},
{
"id": "ec8c8cec-d2a7-4c90-8c9b-12cfeb78d0f6",
"ids": [
"35c7cc36-2ff4-4eb6-bc96-03cc3ea04751",
"389255cb-0c88-45e8-a1dc-6ce9fedbd98c"
],
"quantity": 0,
"code": 0,
"barcode": 0,
"sellPrice": 0
}
],
I've never worked on something like that before. For each combination for example (RED/SMALL), I am storing the 'RED' option id and 'Small' option id.
till now I've tried the following logic, where I want to compare between ids to get the combination as object then process the order as I want:
{product.options.map((opt) => (
<div key={opt.id}>
<h4 className="font-bold">{opt.name}</h4>
<ul className="flex flex-row justify-evenly p-2 px-10 gap-3">
{opt.values.map((val) => (
<li key={val.id}>
<button
key={val.id}
style={{
backgroundColor: val.name,
borderRadius: '50%',
border: '1px solid #C9C9C9',
boxShadow: '0px 0px 5px #C9C9C9',
alignContent: 'center',
alignItems: 'center',
justifyContent: 'center',
width: '30px',
height: '30px',
}}
type="button"
className={`${
comboIds[0] === val.id
? 'border-2 border-black '
: 'bg-white'
} `}
onClick={() => {
comboIds.push(val.id);
let comboTitle = [];
comboTitle.push(val.name);
product.combinations.find((combo) => {
if (combo.ids.join('') === comboIds.join('')) {
return availableCombinations.push({
...combo,
title: comboTitle,
});
} else {
return null;
}
});
console.log(availableCombinations);
}}
>
{opt.type === 'color' ? ' ' : val.name}
</button>
</li>
))}
When user pressed a color for example, I want only available sizes show up and I mean by available sizes is to check for quantity of the pressed color with available sizes.
I appreciate any help. Thank you!

Replacing two objects in an array

I am trying to develop a dynamic DraggableFlatList with react native redux, where the updated array from onDragEnd is dispatched to the store. Hence I am trying to create a function where I use the "from" and "to" parameters from the return object from onDragEnd to alter a new array before dispatch. As an example, in the object below, I work with three items, that are objects from the array:
Object {
"data": Array [
Object {
"backgroundColor": "rgb(154, 0, 132)",
"category": "Practical",
"description": "Zero",
"duedate": Object {
"cond": false,
"date": "",
},
"id": 0.7945943069813785,
"iterations": "",
"key": "0",
},
Object {
"backgroundColor": "rgb(120, 5, 132)",
"category": "Practical",
"description": "One",
"duedate": Object {
"cond": false,
"date": "",
},
"id": 0.8857539547977513,
"iterations": "",
"key": "1",
},
Object {
"backgroundColor": "rgb(184, 10, 132)",
"category": "Practical",
"description": "Two ",
"duedate": Object {
"cond": false,
"date": "",
},
"id": 0.11232602853449736,
"iterations": "",
"key": "2",
},
],
"from": 2,
"to": 1,
}
Here I would like the object with the description "two" to change place with the object with the description "one." The keys don't matter because I give them new keys when I render during render.
The function that is doing the replacement looks like this so far:
const dragComplete = (item) => {
let itemArray = item.data;
// from object is going to be replaced with to object and visa vreca
let indexFrom = item.from;
let indexTo = item.to;
let objMovesFrom = itemArray[indexFrom];
let objMovesTo = itemArray[indexTo];
let sortedArray = itemArray;
console.log('Object moves from : ' + objMovesFrom.description);
console.log('Obejct moves to : ' + objMovesTo.description);
sortedArray.map((task, i) => {
if ((i = indexFrom)) {
sortedArray.splice(indexFrom, 1, objMovesTo);
}
if ((i = indexTo)) {
sortedArray.splice(indexTo, 1, objMovesFrom);
}
});
console.log(item);
//dispatch(setTaskList(item.data));
};
I haven't figured to make any sense of it yet...
Thx for the helpful answers!
How about just simply swapping items?..
const dragComplete = item => {
const {
from: sourceIndex,
to: targetIndex,
data: dragList,
} = item;
// // shallow `item.data` copy for a non mutating approach.
// const swapList = Array.from(dragList);
const dragItem = dragList[sourceIndex]; // swapList[sourceIndex];
const swapItem = dragList[targetIndex]; // swapList[targetIndex];
// simply swap items.
// actively mutate `item.data`. // // `item.data` remains unmutated.
dragList[targetIndex] = dragItem; // swapList[targetIndex] = dragItem;
dragList[sourceIndex] = swapItem; // swapList[sourceIndex] = swapItem;
console.log('Object moves from : ' + dragItem.description);
console.log('Object moves to : ' + swapItem.description);
// return swapList;
};
const sample = {
"data": [{
"backgroundColor": "rgb(154, 0, 132)",
"category": "Practical",
"description": "Zero",
"duedate": {
"cond": false,
"date": "",
},
"id": 0.7945943069813785,
"iterations": "",
"key": "0",
}, {
"backgroundColor": "rgb(120, 5, 132)",
"category": "Practical",
"description": "One",
"duedate": {
"cond": false,
"date": "",
},
"id": 0.8857539547977513,
"iterations": "",
"key": "1",
}, {
"backgroundColor": "rgb(184, 10, 132)",
"category": "Practical",
"description": "Two ",
"duedate": {
"cond": false,
"date": "",
},
"id": 0.11232602853449736,
"iterations": "",
"key": "2",
}],
"from": 2,
"to": 1,
};
console.log({ data: sample.data });
dragComplete(sample);
console.log({ data: sample.data });
.as-console-wrapper { min-height: 100%!important; top: 0; }

How to get complete response data based on text field entry Reactjs

I am facing problem in getting values from rendered data in component that is already outputted on page render. What I need to do is, when someone types in data into text field, it should send it to database but taking that fields data from runtime data.
Currently, when I type something, it says undefined field etc.
This is not form data but a data that need to be update from text field.
So, if user write some xyz in text field, we need to update that data according to the id associated to that field.
I am not able to get data into: console.log(Id, projectId, userId, date, e.target.value)
I have used reduce method that serves the purpose but now I have another use case.
I dont want to set hidden fields as its not the right approach.
The problem is that when someone type data in text field, I need to get that text field data and associated id and respective data from it and pass it ti ajax call.
I need to send that data with ajax but as soon as I type something, it says undefined. I can easily get data from projects array but its of no use to me. I think array reduce method is not good for my use case.
Here is project array:
data = [
{
"id": 27,
"projectno": "007823",
"projectname": "non-A Project 2",
"dailyproof": 1,
"probability": "1.0",
"toleranceregistering": 2,
"customer_name": "Peter",
"user_id": "4",
"days_allocated": "231.0",
"days_real": "5.0",
"hours_real": "6.0",
"project_times": [
{
"id": 11,
"activity": "\"yht\"",
"date": "2020-04-28",
"hours": "2.0",
"project_id": 27,
"token": "\"trr\"",
"user_id": 4,
"created_at": "2020-04-22T12:36:55.479Z",
"updated_at": "2020-04-22T12:36:55.479Z"
},
{
"id": 12,
"activity": "\"yht\"",
"date": "2020-04-03",
"hours": "2.0",
"project_id": 27,
"token": "\"trr\"",
"user_id": 4,
"created_at": "2020-04-22T12:37:08.763Z",
"updated_at": "2020-04-22T12:37:08.763Z"
},
{
"id": 13,
"activity": "\"yht\"",
"date": "2020-04-14",
"hours": "2.0",
"project_id": 27,
"token": "\"dfg\"",
"user_id": 4,
"created_at": "2020-04-22T12:37:19.177Z",
"updated_at": "2020-04-22T12:37:19.177Z"
}
]
},
{
"id": 28,
"projectno": "007333",
"projectname": "non-A Project 2",
"dailyproof": 0,
"probability": "1.0",
"toleranceregistering": 2,
"customer_name": "Peter",
"user_id": "4",
"days_allocated": "231.0",
"days_real": "3.333333333333333333333333334",
"hours_real": "4.0",
"project_times": [
{
"id": 18,
"activity": "\"tgr\"",
"date": "2020-04-16",
"hours": "2.0",
"project_id": 28,
"token": "\"ujy\"",
"user_id": 4,
"created_at": "2020-04-22T12:39:41.465Z",
"updated_at": "2020-04-22T12:39:41.465Z"
},
{
"id": 19,
"activity": "\"ddd\"",
"date": "2020-04-11",
"hours": "2.0",
"project_id": 28,
"token": "\"fff\"",
"user_id": 4,
"created_at": "2020-04-22T12:39:55.020Z",
"updated_at": "2020-04-22T12:39:55.020Z"
}
]
},
{
"id": 29,
"projectno": "00721",
"projectname": "non-A Project 2",
"dailyproof": 1,
"probability": "1.0",
"toleranceregistering": 2,
"customer_name": "Peter",
"user_id": "4",
"days_allocated": "231.0",
"days_real": "5.0",
"hours_real": "6.0",
"project_times": [
{
"id": 22,
"activity": "\"cdf\"",
"date": "2020-04-11",
"hours": "2.0",
"project_id": 29,
"token": "\"fgff\"",
"user_id": 4,
"created_at": "2020-04-22T12:41:26.392Z",
"updated_at": "2020-04-22T12:41:26.392Z"
},
{
"id": 23,
"activity": "\"tg\"",
"date": "2020-04-15",
"hours": "2.0",
"project_id": 29,
"token": "\"ad\"",
"user_id": 4,
"created_at": "2020-04-22T12:41:38.747Z",
"updated_at": "2020-04-22T12:41:38.747Z"
},
{
"id": 24,
"activity": "\"ff\"",
"date": "2020-04-19",
"hours": "2.0",
"project_id": 29,
"token": "\"bbb\"",
"user_id": 4,
"created_at": "2020-04-22T12:41:47.500Z",
"updated_at": "2020-04-22T12:41:47.500Z"
}
]
},
{
"id": 30,
"projectno": "0074",
"projectname": "non-A Project 2",
"dailyproof": 1,
"probability": "1.0",
"toleranceregistering": 2,
"customer_name": "Peter",
"user_id": "4",
"days_allocated": "231.0",
"days_real": "3.333333333333333333333333334",
"hours_real": "4.0",
"project_times": [
{
"id": 25,
"activity": "\"ff\"",
"date": "2020-04-12",
"hours": "2.0",
"project_id": 30,
"token": "\"bbb\"",
"user_id": 4,
"created_at": "2020-04-22T12:42:09.385Z",
"updated_at": "2020-04-22T12:42:09.385Z"
},
{
"id": 26,
"activity": "\"rter\"",
"date": "2020-04-19",
"hours": "2.0",
"project_id": 30,
"token": "\"gfdg\"",
"user_id": 4,
"created_at": "2020-04-22T12:42:19.861Z",
"updated_at": "2020-04-22T12:42:19.861Z"
}
]
}
]
getDaysNumber('2020', '04') {
const dayNums = [];
const daysInMonth = new Date(year, month, 0).getDate();
for (let i = 1; i <= daysInMonth; i++) {
dayNums.push(i);
// console.log(i, ' xxx ');
}
return dayNums;
}
{
data.map((h, index) => (
<TableRow key={`mi-${index}`}>
<TableCell align="right">{h.projectno}</TableCell>
<TableCell align="right">{h.projectname}</TableCell>
<TableCell align="right">{h.customer_name}</TableCell>
<TableCell align="right">{h.days_allocated}</TableCell>
<TableCell align="right">{h.days_real}</TableCell>
<TableCell align="right">{h.hours_real}</TableCell>
{daysNumber.reduce((acc, number, index) => {
const found = h.project_times.find(item => number == item["date"].split('-')[2].replace(/^0+/, ''))
const Id = found && found["id"];
const projectId = found && found["project_id"];
const userId = found && found["user_id"];
const date = found && found["date"];
const hours = found && found["hours"];
found && console.log(Id, projectId, userId, date);
return [...acc,
h.dailyproof == 1 && hours > 0.0 ?
<TableCell align="right" key={`mi-${index}`}
onClick={this.launchCreateContactDialog}>{hours}</TableCell>
:
<TableCell align="right" key={`mi-${index}`}>
<TextField required fullWidth size="small"
variant="outlined"
onKeyUp={(e) => console.log(Id, projectId, userId, date, e.target.value)}/>
</TableCell>
]
}, [])
}
</TableRow>
))
}
This find call may sometimes return undefined.
const found = h.project_times.find(item => number == item["date"]
.split('-')[2]
.replace(/^0+/, '')
)
This is expected when no matches are found. And since it's undefined, all of these will also end up undefined:
const Id = found && found["id"];
const projectId = found && found["project_id"];
const userId = found && found["user_id"];
const date = found && found["date"];
const hours = found && found["hours"];
Therefore, it's not unusual that your console.log statement will log out the value undefined.
It sounds like you're needing to do a few things:
Maintain this data as state in your component.
Add a function to mutate this state.
Add a function to store the state (calling an API)
I don't have enough context to answer #3 for you, but here's the type of pattern you want to go for:
import { useEffect, useState } from 'react';
function HoursEntry() {
const [state, setState] = useState();
useEffect(() => {
// Do your data fetching here; for now will use your constant
setState(data);
}, []);
function updateHours({ userId, projectId, hourEntryId, date, hours }) {
// Build newData based on the changes...
setState(newData);
}
// All the rendering stuff. Rendered components should be mappings of what's in
// state...
<TextField
required fullWidth
size="small"
variant="outlined"
value={hours}
onChange={(e) => updateHours({
userId,
projectId,
hourEntryId: Id,
date,
hours: parseFloat(e.target.value)
})}/>
// ...
}
Inside of your updateHours function, you'll create a new copy of your data with the expected modifications. For example, if you're updating an existing object, you'll update its hours property. If you're updating something for which there is no record, you'll create a new one, etc. The key is your call to setState to update the data in your component.
Then, once you have your submit button or whatever method you've got to store, you'll reference this state for the latest copy of your data.
That's the general pattern for any kind of form entry component; it's an exercise in updating state.

Categories