React native get a specific element value from state array - arrays

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

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;
}
})

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

how to decrement count value that is in a nested array within a reducer

I need to increment, and decrement on each click(its for a like button). I figured out the logic to increment a like value, but how would i go about decrementing the value ?
The count is pretty much the length of the array, how many likes for that particular post/image.
So here is the logic that increments the like value, and this works, it will increment to infinity, which is not what i want. Im looking for is the reducer logic that will take care of the decrement value, just as the POST_LIKE_SUCCESS does
console.log( newState.images.find(image => image.id === action.data).likes)
data structure as followed
Data structure.
{
"id": 154,
"image_title": "iiisdd",
"img_url": "https://res*******",
"created_at": "2019-07-18T19:44:49.805Z",
"updated_at": "2019-07-18T19:44:49.805Z",
"user_id": 1,
"user": {
"id": 1,
"googleId": null,
"username": "E*******",
"password": "$***********JwCO",
"email": "e******",
"created_at": "2019-06-23T18:57:17.253Z",
"updated_at": "2019-06-23T18:57:17.253Z"
},
"comments": [
{
"id": 51,
"comment_body": "owls life",
"created_at": "2019-07-18T20:04:51.484Z",
"updated_at": "2019-07-18T20:04:51.484Z",
"user_id": 8,
"image_id": 154,
"user": {
"id": 8,
"googleId": null,
"username": "guest",
"password": "$************",
"email": "***********l.com",
"created_at": "2019-07-18T20:04:34.315Z",
"updated_at": "2019-07-18T20:04:34.315Z"
}
},
{
"id": 52,
"comment_body": "dadad",
"created_at": "2019-07-19T20:16:40.103Z",
"updated_at": "2019-07-19T20:16:40.103Z",
"user_id": 1,
"image_id": 154,
"user": {
"id": 1,
"googleId": null,
"username": "**********",
"password": "$*********O",
"email": "e*******m",
"created_at": "2019-06-23T18:57:17.253Z",
"updated_at": "2019-06-23T18:57:17.253Z"
}
},
{
"id": 53,
"comment_body": "test",
"created_at": "2019-07-21T22:12:44.729Z",
"updated_at": "2019-07-21T22:12:44.729Z",
"user_id": 1,
"image_id": 154,
"user": {
"id": 1,
"googleId": null,
"username": "E******d",
"password": "$********4WjO",
"email": "********",
"created_at": "2019-06-23T18:57:17.253Z",
"updated_at": "2019-06-23T18:57:17.253Z"
}
}
],
"likes": [
{
"id": 24,
"user_id": 2,
"image_id": 154,
"created_at": "2019-07-22T19:26:27.034Z",
"deleted_at": "2019-07-22T19:26:27.034Z",
"restored_at": "2019-07-22T19:26:27.034Z",
"updated_at": "2019-07-22T19:26:27.034Z"
},
{
"id": 77,
"user_id": 1,
"image_id": 154,
"created_at": "2019-07-23T02:55:31.051Z",
"deleted_at": "2019-07-23T02:55:31.051Z",
"restored_at": "2019-07-23T02:55:31.051Z",
"updated_at": "2019-07-23T02:55:31.051Z"
}
]
}
I want to delete the like, similar to redux boilerplate counter like this.
state - 1
reducer
import {
UPLOAD_IMAGE_SUCCESS,
POST_COMMENT_SUCCESS,
DELETE_IMAGE_FAILURE,
FETCH_IMAGES_SUCCESS,
DISLIKE_POST_SUCCESS,
POST_COMMENT,
POST_LIKE,
POST_LIKE_SUCCESS,
POST_LIKE_FAILURE,
DELETE_IMAGE_SUCCESS,
} from '../actions/types';
const initialState = {
images: [],
likedByuser: false,
};
export default (state = initialState, action) => {
switch (action.type) {
case FETCH_IMAGES_SUCCESS:
return {
...state,
images: action.images,
};
.....
case DELETE_IMAGE_SUCCESS:
// console.log(action)
return {
...state,
images: state.images.filter(img => img.id !== action.data),
};
case DELETE_IMAGE_FAILURE:
return {
...state,
error: action.error,
};
case POST_LIKE_SUCCESS:
console.log(action.data);
const newState = { ...state }; // here I am trying to shallow copy the existing state;
const existingLikesOfPost = newState.images.find(image => image.id === action.data).likes;
console.log(existingLikesOfPost)
newState.images.find(image => image.id === action.data).likes = [...existingLikesOfPost, action.newLikeObject]; // using this approach I got some code duplication so I suggested the first approach of using **push** method of array.
// console.log(newState)
return newState;
case DISLIKE_POST_SUCCESS:
console.log(action.data)
// working on logic that will decrement
return{
...state - 1
}
default:
return state;
}
};
console.log(action.data)
{
"type": "POST_LIKE",
"data": {
"id": 154,
}
}
express backend logic
router.post('/like/:id', (req, res) => {
const { id } = req.params;
if (id !== null || 'undefined') {
Image.forge({ id })
.fetch({ withRelated: ['user', 'comments', 'likes'] })
.then((likes) => {
const like = likes.toJSON();
// console.log(like.likes);
const existingUserlikes = like.likes.map(user => user.user_id);
// checking to see if a user already liked his own post
// if existing user does not have user id, user can like post,
// else if user already like this post wont be able to.
const newLike = new Likes({
image_id: id,
user_id: req.user.id
});
if (existingUserlikes.includes(req.user.id)) {
// !newLike do not create a new row of likes if like from this user already exists
if (!newLike) {
Likes.forge().where({ user_id: req.user.id, image_id: id }).destroy();
}
return Likes.forge().where({user_id: req.user.id, image_id: id }).fetch()
.then((like) => like.destroy()
.then( () => res.json({ error: true, data: { message: 'like deleted' } })));
}
newLike.save().then(like => res.status(200).json({ status: 'You liked this post', like: newLike }));
});
}
});
I feel like you are complicating things. Personally, I wouldn't structure my data like that. Deeply nested objects should be avoided. You can instead have several objects that are linked to each other. Also, I would have the post ids as object keys, so when I want to update a specific post, I just need to
return {
...state,
[action.id]: {
...state[action.id],
...action.newData,
}
}
In your case, I would just filter out the user id that disliked the post:
...
case DISLIKE_POST_SUCCESS:
const newState = { ...state };
const predicate = ({ id }) => id === action.data;
const existingLikes = newState.images.find(predicate).likes;
// You would have to pass userId as an action payload as I'm assuming you are deleting
// the likes based on the userId.
const newLikes = existingLikes.filter(({ user_id }) => user_id !== action.userId);
newState.images.find(predicate).likes = newLikes;
The easiest thing would be to use an immutability-helper. This enables you to update an object immutable without worrying about the whole object.
You could update it like this:
return update(state, {
likes: {$remove: [action.id]}
});
If you change your like object later on, you don't have to change this part of the code, because it will only update the mentioned data.

Angular2 filter object array based on value inside property(nested filters)

I need to retrieve only the object that have the name ... as a participant using a filter(pipe).
Every object has an array of participants objects. This is what it looks like(see my example Json at the end)
-object
-- _id
-- participants
-- participant1
-- participant2
So this is what I tried:(hardcoded Jack to get a match...)
import { Pipe, PipeTransform } from "#angular/core";
#Pipe({ name: 'filter' })
export class Gamefilter implements PipeTransform {
public transform(values: any[], filter: string): string {
if (!values || !values.length) "";
if (!filter) return JSON.parse(JSON.stringify(values));
return JSON.parse(JSON.stringify(
values.filter((element) => {
return element.participants.filter((item)=> {
return item.name.indexOf("Jack") > 1;
});
})
));
}
}
Altough this doesn't work, and I can't see the mistake I made.
I tried this to (from Filtering array of objects with arrays based on nested value ):
values.filter((element) =>
element.participants.some((subElement) => subElement.name === "Jack"))
.map(element => {
let newElt = Object.assign({}, element); // copies element
return newElt.participants.filter(subElement => subElement.name === "Jack");
})
I also saw this post but could get the right answer for me: Filtering array based on value in deeply nested object in javascript
The example JSON:
[
{
"_id": "5925ae95675e19001106e940",
"createdOn": "2017-05-24T16:02:29.229Z",
"participants": [
{
"_id": "jack19302",
"name": "Jack",
"__v": 0
},
{
"_id": "donald38902",
"name": "Donald",
"__v": 0
}
]
},
{
"_id": "5925ae95675e19001106e990",
"createdOn": "2017-05-24T16:02:29.229Z",
"participants": [
{
"_id": "donald38902",
"name": "Donald",
"__v": 0
}
]
},
{
"_id": "5925ae95675e19001106e996",
"createdOn": "2017-05-24T16:02:29.229Z",
"participants": [
{
"_id": "jack19302",
"name": "Jack",
"__v": 0
}
]
}
]

updating a JSON array in AWS dynamoDB

My document looks like this:
{
"data": {
"eventId": "20161029125458-df-d",
"name": "first",
"purpose": "test",
"location": "yokohama",
"dateArray": [],
"attendees": [
{
"attendeeId": "2016102973634-df",
"attendeeName": "lakshman",
"personalizedDateSelection": {}
},
{
"attendeeId": "2016102973634-tyyu",
"attendeeName": "diwaakar",
"personalizedDateSelection": {}
}
]
}
}
Say, I need to update the attendee JSON array with attendeeId: 2016102973634-df. I tried many ways ways using update and condition expression, but no success.
Here is my try:
const params = {
TableName: "event",
Key: {
"eventId": eventId
},
UpdateExpression: "SET attendees[???] = ",
ConditionExpression: attendees.attendeeId = "2016102973634-df",
ExpressionAttributeValues: {
":attendee" : attendeeList
},
ReturnValues: "ALL_NEW"
};
dynamo.update(params, (err, data) => {
if (err) {
return reject(err);
}
console.log(data.Attributes);
});
Could not find any resources for updating an Json in a array.
After #notionquest's comment:
- Have not used any JsonMarshaller. Initially I added the empty array to attendees field like this:
{
"eventId": "20161029125458-df-d",
"name": "first",
"purpose": "test",
"location": "yokohama",
"dateArray": [],
"attendees": []
}
and then When a new attendee comes I add it to the attendees property like this:
const attendee = {
"attendeeName": "user1",
"personalizedDateSelection": {"today": "free"}
}
const attendeeList = [attendee];
const eventId = "20161029125458-df-d";
const params = {
TableName: "event",
Key: {
"eventId": eventId
},
UpdateExpression: "SET attendees = list_append(attendees, :attendee)",
ExpressionAttributeValues: {
":attendee" : attendeeList
},
ReturnValues: "ALL_NEW"
};
dynamo.update(params, (err, data) => {
if (err) {
return reject(err);
}
console.log("in update dynamo");
console.log(data.Attributes);
});
As you have seen in the above snippets, initially I add empty [] array and add a new attendee using the above code. Now, How do I update a specific JSON in an array. If you say that is not possible, what else can I try?
Should I try this :
Get the Full JSON.
Manipulate the JSOn and change the things I want in my nodeJS.
And then update the new JSON to dynamoDB.
But this consumes two calls to dynamoDB which seems to be inefficient.
Would like to know If there is any round way ?
you can store the index of list. while updating the list we can use them. For example ,
{
"data": {
"eventId": "20161029125458-df-d",
"name": "first",
"purpose": "test",
"location": "yokohama",
"dateArray": [],
"attendees": [
{
"index":0,
"attendeeId": "2016102973634-df",
"attendeeName": "lakshman",
"personalizedDateSelection": {}
},
{
"index":1,
"attendeeId": "2016102973634-tyyu",
"attendeeName": "diwaakar",
"personalizedDateSelection": {}
}
]
}
}
const params = {
TableName: "event",
Key: {
"eventId": eventId
},
UpdateExpression: "SET attendees[attendee.index].attendeeName = :value",
ExpressionAttributeValues: {
":value" : {"S":"karthik"}
},
ReturnValues: "ALL_NEW"
};
dynamo.update(params, (err, data) => {
if (err) {
return reject(err);
}
console.log(data.Attributes);
});
An example of an update query:
Data structure (saved in DynamoDB)
{
tenant_id: 'tenant_1',
users: {
user1: {
_id: 'user1',
email_address: 'test_email_1#gmail.com'
},
user2: {
_id: 'user2',
email_address: 'test_email_2#gmail.com'
}
}
}
Data for update (used in the params)
var user = {
email_address: 'updated#gmail.com'
}
Params
var params = {
TableName: 'tenant-Master',
Key: {
"tenant_id": 'tenant_1'
},
UpdateExpression: "set #users.user1 = :value",
ExpressionAttributeNames: {
"#users": "users"
},
ExpressionAttributeValues: {
":value": user,
},
};
Explanation
By switching to a map of maps from an array of maps we can now use UpdateExpression: "set #users.user1 = :value" to update our nested object at the map of users with the id of user1.
NOTE: This method as is will REPLACE the entire map object at users.user1. Some changes will need to be made if you want to keep pre-existing data.
I could not find any answer to query and update the JSON-array. I think this may be AWS profitable motive to not allow those features. If you need to query on a particular ID other than primary key, you need to make a secondary index which is cost effective. This secondary index cost is additional to the dyn
amoDB table cost.
Since, I did not want to pay extra bucks on secondary index, I changed my dynamoDB schema to the following:
{
"data": {
"eventId": "20161029125458-df-d",
"name": "first",
"purpose": "test",
"location": "yokohama",
"dateArray": [],
"attendees": {
"2016102973634-df": {
"attendeeId": "2016102973634-df",
"attendeeName": "lakshman",
"personalizedDateSelection": {}
},
"2016102973777-df": {
"attendeeId": "2016102973777-df",
"attendeeName": "ffff",
"personalizedDateSelection": {}
}
}
}
}
Changing attendees from [] to {}. This allows me the flexibility to query particular attendeeId and change the entire JSON associated with that. Even though, this is a redundant step, I do not want to spend extra bucks on my hobby project.

Resources