A way to access json data - reactjs

I am importing a json file as 'data' to use it as a initial state of chatList. However,
Property does not exist on type
keeps showing up. Is there a way that I can access chats in data? ->
data is an array too, so it should be for example data[0].chats –
Apostolos : Thanks a lot!
[
{
"partnerId": "user1",
"chats": [
{
"userId": "user0",
"message": "Olaf, you are melting!",
"msgId": 1644809969390
},
{
"userId": "user1",
"message": "Some people are worth melting for",
"msgId": 1644809969387
}
]
},
{
"partnerId": "user2",
"chats": [
{
"userId": "user2",
"message": "11111",
"msgId": 1644809969392
},
How can I access certain partnerId so that I can filter chats and set as the initial state of chatList?

If you want to filter by a specific partnerId, then you should do the following:
const [chatList, setChatList] = useState<IChat[]>(data
.filter(dt => dt.partnerId === 'ABCD')
.map(t => t.chats).flat()
.filter(user => user.userId === 'XYZ')

Related

How filter and delete object with null or empty property in json query

I have this json :
{
"meta": {
"status": 200,
"pagination": {
"page": 1,
"perPage": 15,
"hasNext": true
}
},
"data": [
{
"id": "1",
"title": "Movie title1"
"rating": null,
"playProviders": [
]
},
{
"id": "2",
"title": "Movie title2"
"rating": {
"ratingAssessment": "7.1"
},
"playProviders": [
"HBO", "Netflix"
]
},
....
}
I want to create a page with a list of movies, I need to fetch movies but only those which have a rating and playProviders, what parameters should I use in this request?
https://api.com/movies?orderBy=views
When I filters in the code:
programs.filter((program) => program.rating !== null);
it only gets a few films per page, those that don't have null. For example, 15 are per page and I get 2. How do I filter this? (I am using react typescript)
I don't have access to the API code. I need to filter what is returned by the API or write a query so that you get already filtered data from the API.
programs = [
{rating: 1,
playProviders: ["sf"]
},
{
rating: 4,
playProviders: []
}
]
programs.filter(function(program) {
if (program.rating !== null && program.playProviders.length !== 0) {
return program;
}
})

Update single record in nested state object, react-redux

I am working on a grid structure where user can add sections, sub-sections or items dynamically. I am managing that things in my redux state object. UI of my grid is as following :
I want to update a single row record instead of reloading whole grid again. For that, whenever user changes any cell value of row i am calling update-row api and on success of that i am trying to update that value in reducer using following code.
case UPDATE_ORDER_LINES_SUCCESS:
let stateData = state.get(`GridData`);
const dataIndex = stateData.children.findIndex(
(listing) => listing.id === action.row.id // row id which is updated
);
stateData[0].children[dataIndex] = action.row;
let data = Object.assign(stateData, { children: stateData.children });
state = state.set(`GridData`, [data]);
This code is working fine for first level of children records (as per json object) but problem occur if user update value of nth level children record. How can i update that row record in my redux state ?
My current redux state sample is :
{
"views": [
{
"id": "5e6b8961ba08180001a10bb6",
"viewName": "house",
"description": "house view",
"name": "house",
"children": [
{
"id": "5e6b8961ba08180001a10bb7",
"viewName": "house",
"sectionName": "Temporary",
"sectionId": "SEC-02986",
"description": "Temporary",
"sequenceNumber": 4,
"refrenceId": "SEC-02986",
"children": [
{
"id": "5e590df71bbc71000118c109",
"lineDescription": "AutoPickPack01",
"lineAction": "Rent",
"quantity": 5,
"deliveryDate": "2020-02-29T06:00:00+11:00",
"pickDate": "2020-02-28T06:00:00+11:00",
"pickupDate": "2020-03-01T06:00:00+11:00",
"prepDate": "2020-02-28T06:00:00+11:00",
"returnDate": "2020-03-01T06:00:00+11:00",
"shippingDate": "2020-02-29T06:00:00+11:00",
"unitPrice": 7000,
"children": [
{
"id": "5e590df71bbc71000118c10a",
"orderId": "Ord-05788_1",
"lineNumber": "01a7b77c-792a-4edb-9b73-132440621968",
"purchaseOrderNumber": null,
"lineDescription": "29Janserial",
"lineAction": "Rent",
"quantity": 5,
"pricingMethod": "Fixed",
"displayUnit": "Days",
"unitPrice": 0,
"chargeAmount": 0,
"pickDate": "2020-02-17T06:00:00+11:00",
"prepDate": "2020-02-28T06:00:00+11:00",
"shippingDate": "2020-02-29T06:00:00+11:00",
"deliveryDate": "2020-02-29T06:00:00+11:00",
"pickupDate": "2020-03-01T06:00:00+11:00",
"returnDate": "2020-03-01T06:00:00+11:00",
"name": "29Janserial",
"description": "29Janserial",
"discountAmount": "",
"discountPrice": ""
}
]
}
]
}
]
}
]
}
What is the best way to update nested children row data in reducer ?
As redux doesn't allow to mutate the current state and return it back, it's hard to modify a nested child. Although its highly discouraged to
have this kind of nested structure in redux, rather it should be normalized as #bsapaka answered. But if you still want to update the nested
object and return the whole state as an immutable one, immer should be your friend. immerJS has been so popular for handling immutable states.Although
Install immer and redux-immer in your case
yarn add immer redux-immer
In your reducers.js file where all reducers have been combined using combineReducers
import produce from 'immer';
import { combineReducers } from 'redux-immer';
// Replace your current combineReducers with
combineReducers(produce, { /* Object of all reducers */ });
In your current reducer file
import product from 'immer';
const findNestedChild = (arr, itemId) => (
arr.reduce((a, item) => {
if (a) return a;
if (item.id === itemId) return item;
if (item['children']) return findItemNested(item['children'], itemId)
}, null)
);
case UPDATE_ORDER_LINES_SUCCESS:
return produce(state, draftState => {
const { row: newChild, row: { id }} = action;
let child = findNestedChild(draftState.views, id);
child = newChild;
});
You should normalize your state, which flattens the tree, and entities become associated by id references instead of direct nesting.
For example
{
"entities": {
"orders": {
"o1": { "id": "o1", "productIds": ["p1", "p2"] },
"o2": { "id": "o2", "productIds": ["p2", "p3"] },
"o3": { "id": "o2", "productIds": ["p3"] }
},
"products": {
"p1": { "id": "p1", "orderIds": ["o1"] },
"p2": { "id": "p1", "orderIds": ["o1", "o2"] },
"p3": { "id": "p1", "orderIds": ["o2", "o3"] }
},
"views": {
"v1": { "id": "v1", "childIds": ["v1.1", "v1.2"] },
"v1.1": { "id": "v1.1", "parentId": "v1" },
"v1.2": { "id": "v1.2", "parentId": "v1" }}
},
"ids": {
"orders": ["o1", "o2", "o3"],
"products": ["p1", "p2", "p3"],
"views": ["v1", "v1.1", "v1.2"]
}
}
There's more upfront work of finding the correct model and transforming the raw data into it, but you save a lot of time not having to deal with updates that are nested or affect multiple areas of data.
Redux docs on normalizing
A (de)normalization transformation tool
A reducer utility library to manage normalized state

CastError: Cast to ObjectId failed for value 'xxx' at path "_id"

I have an array in request as:
{
"acceptedBookings": [
{
"id": "e1f66d7a852986709f665c3",
"Date": "2020-02-04T05:03:25.332Z"
}
]
}
I want to update the "date" for every "id". However If I search as
await Booking.findById( acceptedBookings[0].id ) or
await Booking.findOne({_id : acceptedBookings[0].id})
It does not give a response
You're accessing wrong member, what you want is:
let's assume your map is something like
const acceptedBookings = {
"accepted": [{
"id": "e1f66d7a852986709f665c3",
"Date": "2020-02-04T05:03:25.332Z"
},
{
"id": "i123",
"Date": "2020-02-04T05:03:25.332Z"
},
{
"id": "i123",
"Date": "2020-02-04T05:03:25.332Z"
}
]
};
console.log(acceptedBookings.accepted[0].id); // e1f66d7a852986709f665c3
console.log(acceptedBookings.accepted[1].id); // i123
await Booking.findById( acceptedBookings.accepted[0].id ) //should work fine
Remember the object you've created that is not an array it's map/object with a key: value pair
thus get the right array/element first then access it's members

React native get a specific element value from state array

I am new to React-Native i am building a sample app, But i ha d small problem with this.state.array , I want a particular element value from array
my array is
this.state.userDetail: [
Object {
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
},
]
````````````````````````````````````````
In the above array i want user_id value ,
i tried different methods like
```````````````````````````
this.setState({ user_id: this.state.user_Details.user_id })
const item_id = this.state.user_Details.map((item) => { item.user_id });
var item_id = this.state.user_Details.filter(userDetails => { return userDetails[7]; })
``````````````````````````````````````````
but nothing will work i want only user_id value to update the users table , So please any help ..
If you wish to extract the user_id SPECIFICALLY from this example:
[
{
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
},
]
and assuming this data is in your this.state.userDetail property.
The only thing you need is:
this.state.userDetail[0].user_id
Why this might not be working for you:
this.state.userDetail: [
Object { /// What's Object?
And if you are trying to parse more than 1 entry in the array unlike your example, you first need to select a certain entry with a 'for' loop or a .map() function.
I think you want to get one index user id, so I give the following code:
// define it in the constructor, and it may have more than one items
this.state.userDetail: [
{
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
},
]
// do not directly assign use this.state.x
let copyUserDetails = {...this.this.state.user_Details}
let userIdsArray = copyUserDetail.map((item) => { return item.user_id });
let itemId = userIdsArray[0]
console.log("the first user Id is",itemId)
// if you only want to the user_id, you can directly copyUserDetails[0].user_id
let userId = copyUserDetails[0].user_id
console.log("the first user Id is ==> ",userId)
this.setState({ user_id: itemID })
// the filter is accordng some condtion to return a new arry
let itemFilterArray = copyUserDetails.filter((element,i) => {
// filter the item which match some condition, for example the uerId not equal
//0
if(element.user_id !== 0){
return element
}
})
according to your require, I give the following code:
//if you do not have many userInfo
constructor(props){
super(props)
this.state= {
user_Details: {
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
}
}
// somewhere you want the userId
getUserId = () => {
return this.state.user_Details.user_id
}
}
//if you have many userinfo
constructor(props){
super(props)
this.state= {
user_Details: [{
"creation_Date": "2019-10-22T06:34:52.000Z",
"mobile": 9985849955,
"name": "siva",
"password": "123456",
"picture_url": "5.jpg",
"role": "",
"user_id": 1,
}]
}
// somewhere you want the some index userId
getUserId = (index) => {
// do not directly assign use this.state.x
let copyUserDetails = {...this.this.state.user_Details}
return copyUserDetails[index].user_id
}
//somwhere you want all the userId
getUserId = () => {
// do not directly assign use this.state.x
let copyUserDetails = {...this.this.state.user_Details}
let userIdArray = copyUserDetail.map((item) => { return item.user_id });
return userIdArray
}
}
and I suggest you can read the api about json and array

How to modify a complex JSON Object in using Immutable

I have below JSON and wanted to update the value depending on Aid, Bid and Cid using Immutable.js
e.g.
Below input provided.
Aid= A, Bid = 1, Cid= 4, NewValue = 'FOUR'
If above input is provided the value "One" needs to be changed to "FOUR"
let sampleJson = {
Aid: 'A', detail:"sample", list: [
{
"Bid": "1",
"group": [
{
"name": "Group A",
"Cid": "4",
"value": "One"
},
{
"name": "Group A",
"Cid": "41",
"value": "1"
},
]
},
{
"Bid": "2",
"group": [
{
"name": "Group A",
"Cid": "4",
"value": "1"
},
{
"name": "Group A",
"Cid": "4",
"value": "1"
},
]
};
I was able to access the value using below code. How can i return the entire JSON with updated value?
let variale = Immutable.fromJS(sampleJson).
getIn(['list']).
find(allocation => allocation.get("Bid") === "1").
getIn(['group']).
find(fun => fun.get("Cid") === "4").set('value',"FOUR");
Anyone has any suggestions on how to resolve this problem?
I think you can try to do this like so:
let immutable = Immutable.fromJS(sampleJson);
immutable = immutable.setIn(['list', 0, 'group', 0, 'value'], 'FOUR');
This monstrosity is how I would do it:
const newData = originalData.update('list', list => {
const itemIndex = list.findIndex(item => item.get('Bid') === '2');
return list.update(itemIndex, listItem => {
return listItem.update('group', groupList => {
const groupIndex = list.findIndex(group => group.get('Cid') === '4');
return groupList.update(groupIndex, group => {
return group.set('value', 'FOUR');
});
});
});
});
https://jsbin.com/latupo/7/edit?html,js,console
Personally I stopped using Immutable, I always found it a bit painful (not to mention those docs!). I now use redux and good old cloning to not mutate state. Less performant in theory but if you've got nothing that runs over a few milliseconds anyway, save yourself the trouble...

Resources