Redux-thunk - How to structure fetched data to index storage pattern? - redux

I am using Redux + Redux-thunk to fetch datas from my API.
The data returned by my thunk is an array that looks like this :
[
{id_user: 1, name: "Joe", surname: "M", email: "joe#email.fr"},
{id_user: 2, name: "Jimmy", surname: "S", email: "jimmy#email.fr"},
{id_user: 9, name: "Jhonny", surname: "H", email: "jhonny#email.fr}
]
What I would like to do but don't get how to, is to store this data in my global state using the index storage pattern.
For exemple, from the fetched array showed above, the data structure I would like to store would look like this :
{
"usersById": {
1: {
id_user: 1,
name: "Joe",
surname: "M",
email: "joe#email.fr"
},
2: {
id_user: 2,
name: "Jimmy",
surname: "S",
email: "jimmy#email.fr"
},
9: {
id_user: 9,
name: "Jhonny",
surname: "H",
email: "jhonny#email.fr
}
}
}
Here is how I tried doing it in my success user fetch action creator :
export const fetchUsersSuccess = (users) => ({
type: types.FETCH_USERS_SUCCESS,
users: users.map(user =>
'userById': {
[user.id_user]: {
id_user: user.id_user,
name: user.name,
surname: user.surname,
email: user.email,
}
}
}),
loading: false,
});
The problem is, this still returns an array, looking like this :
[
userById: {
1: {
id_user: 1
name: "Joe"
surname: "M"
}
},
userById: {
2: {
id_user: 2
name: "Jimmy"
surname: "S"
}
},
userById: {
9: {
id_user: 9,
name: "Jhonny",
surname: "H"
}
},
]
I searched around but could not get an answer for this. I also tried to format the fetched data from the fetching thunk directly but I think this is not the solution ? Am I wrong ?
Or maybe this logic should go to the reducer ?
I know this must be simple stuff but I can't get over it, making me trying over-complicated things for, I guess, something as simple as this.
Any help would be greatly appreciated. Thank you very much

Our official Redux Toolkit package specifically has a createEntityAdapter API that implements managing data in a normalized form in the store.
For examples of how to use it, see the "Redux Essentials" core docs tutorial, Part 6: Performance and Normalizing Data, and the "Managing Normalized Data" section in the Redux Toolkit Usage Guide.

Related

I need to all users and for each user all tokens in sequelize

I have a schema in sequelize that a user has many tokens, I need to get all users and for each user, I need to have all tokens. The id of user is saved in Token table as FK.
I created this below but did not work
await Model.Users.findAll({
attributes: ['id'],
include: [
{
model:Model.Token,
attributes: ['token']
}
]
});
The response I want to have back is like below
[
{ id: 2, Tokens: [{token: sdasdasdasdweqrewrfwe}, {token: test}] },
{ id: 6, Tokens: [{token: test2}, {token: test3}] },
.
.
]
Thanks
Problem was not in code but in sequelize table connection, if you have same problem please check the connection
db.User.hasMany(db.Token, {
onDelete: "CASCADE",
onUpdate: "CASCADE",
foreignKey: 'user_id'
});

Flutter Firestore understanding joins

I am doing this in Flutter, with a Firebase database, using the Firestore packages in Flutter. I would like to know how a join is done in noSQL (or more specifically, in Flutter-Firestore)
This is what my database looks like:
users: {
U1: {
name: 'Peter',
surname: 'Jensen'
},
U2: {
name: 'Marry',
surname: 'Kown'
},
...
}
groups: {
G1: {
name: 'Group 1'
},
G2: {
name: 'Group 2'
},
...
}
members: {
M1: {
userId: U1,
groupId: G1
},
M2: {
userId: U1,
groupId: G2
},
M3: {
userId: U2,
groupId: G1
},
...
}
Now how do I do a join to get something like this:
members: {
M1: {
userId: {
name: 'Peter',
surname: 'Jensen'
},
groupId: {
name: 'Group 1'
}
},
M2: {
userId: {
name: 'Peter',
surname: 'Jensen'
},
groupId: {
name: 'Group 2'
}
},
M3: {
userId: {
name: 'Marry',
surname: 'Kown'
},
groupId: {
name: 'Group 1'
}
},
...
}
Do I do:
const users = await Firestore.instance.collection('users').getDocuments();
const groups = await Firestore.instance.collection('groups').getDocuments();
const members = await Firestore.instance.collection('members').getDocuments();
...manually loop through everything and assign everything myself
(I need to add more text because I have 'mostly code'): I would assume the above would use of a lot of query data in Firebase, so I can't see how this would be a good idea. I actually just want to see in what groups is a user a in
If you have groups and members, I'd typically store the follow data:
A list of users in a users collection.
For each user I'd keep their properties and a list of the group IDs of the groups they're a member of.
A list of groups in a groups collection.
For each group I'd keep their properties
Note that you could model the nested list as a subcollection, but typically this is not needed. With the above model you can easily find what groups a user is part of, even even do a query for users who are part of a certain group with an array-contains clause.
To get a list of the properties of the group for a specific user, you'll indeed need to load that user, and their groups separately. This is normal with many NoSQL databases, and not necessarily as slow as you may expect. But if performance is not good enough, you can consider duplicating some data to reduce the need for joins. It all depends on your needs, and unlike in relational data models, NoSQL is not dogmatic about such things.
To learn more about this topic:
read NoSQL data modeling
watch Getting to know Cloud Firestore

Firebase data modeling for inequality check

i've been developing a mobile app with react native & firebase realtime db, and i'm stuck with a data-modeling problem.
My app will let users to vote photos that uploaded by other users and each user will be allowed to vote once for each photo. I'm providing a tinder-like UI for voting action. I'm planning to have users and photos trees on the firebase looks like this, which is pretty straight forward:
{
users:{
userId1: {
name:'John'
surname: 'Doe',
votedPhotos: {
somePhotoId: {
timestamp: 1528836856000
},
somePhotoId2: {
timestamp: 1529363754000
},
...
},
...
},
userId2: {
name:'Johnny'
surname: 'Doerr'
...
},
...
},
photos: {
photoId1: {
url: 'https://a-firebase-storage-url',
owner: {
uid: 'userId1',
fullName: 'John Doe'
},
upvoteCount: 12,
downvoteCount: 8
},
photoId2: {
url: 'https://another-firebase-storage-url',
owner: {
uid: 'userId2',
fullName: 'Johnny Doerr'
},
upvoteCount: 28,
downvoteCount: 4
},
...
}
}
I need to prevent users to vote their own photos and vote a photo more than once. So i need to query photos as excluding already voted photos and self uploaded photos for a user. If i was using a traditional db it would be easy as a pie but i couldn't figure out how to do that query in a firebase realtime database since i can't use not_equals or not_in. How would you suggest me to model my data?
Record user votes under the photouid. I imagine a .length could provide you the total votes.
photos
photo1-uid
owner:user1-uid
votes:{
user2-uid: true,
user3-uid: true
}

Getting 'query in command must target a single shard'

I have a CosmosDB setup using the Mongo API. I have a collection with a hashed shard on one of the field of the document. When I run commands like db.collection.remove or db.collection.deleteMany I get the following error.
Command deleteMany failed: query in command must target a single shard key.: {"message":"Command deleteMany failed: query in command must target a single shard key."}
I'm not sure how can I mention a shard key as part of the query considering I want the query to run across all the shards.
You need to provide shard key when you want to run commands like db.collection.remove or db.collection.deleteMany.
For example :
My data source as below:
[
{
"id" : "2",
"name" : "b"
},
{
"id" : "1",
"name" : "a"
}
]
And my shared key is "/name". Use db.coll.deleteMany({"name":"a"}) to delete specific shard.
Hope it helps you.
It should be ShardKey which you have chosen when you created cosmosDb collection.
FilterDefinition<Product> filter = Builders<Product>.Filter.Eq("id", 2);
=== 2 is my shardKey
await this._dbContext.GetProducts.DeleteOneAsync(filter);
return RedirectToAction("Index");
Kindly refer an image below , how does it look like in CosmosDB
Shard Key(Partition Key) has to be provided during specification of schema model in the code. Once its provided, we can perform regular operation like save, update and delete as usual.
Example:
const mySchema = new Schema({
requestId: { type: String, required: true },
data: String,
documents: [{ docId: String, name: String, attachedBy: String }],
updatedBy: {
type: {
name: { type: String, required: true },
email: { type: String, required: true },
}, required: true
},
createdDate: { type: Date, required: true },
updatedDate: { type: Date },
}, { shardKey: { requestId: 1 } }
);
In the above code we specified requestId as Shard Key, now we can perform any mongo operations
Example:
let request:any = await myModel.findById(requestId);
request.data ="New Data";
await request.save();
Hope that helps.
This works with all Mongo operations

Breeze, database first and anonymous objects

I'm using the ASP.Membership provider and I've created an additional table for the user data. I'm only experimenting and I'm not worried about security or anything like that. I'm only concerned with the big picture.
I'm experimenting with Breeze, SPA, Entity Framework, and Web.API and perhaps I'm rushing in too fast before I'm getting a good grasp on the individual concepts.
My Breeze query looks like this:
[HttpGet]
public IQueryable<object> Users()
{
return (
from user in _contextProvider.Context.Users
join membership in _contextProvider.Context.Memberships on user.UserId equals membership.UserId
join userProfile in _contextProvider.Context.UserProfiles on user.UserId equals userProfile.UserId
select new { user, membership, userProfile}
);
}
My results looks like this (only first record shown):
{
$id: "1",
$type: "<>f__AnonymousType4`3[[SPA01.EntityFramework.User, SPA01],[SPA01.EntityFramework.Membership, SPA01],[SPA01.EntityFramework.UserProfile, SPA01]], SPA01",
user: {
$id: "2",
$type: "SPA01.EntityFramework.User, SPA01",
UserId: "dd59fcd1-9d88-4494-a37c-1c25155cb77d",
ApplicationId: "23042eba-1113-4e56-8ac6-4640120ecc6c",
UserName: "DHaworth",
IsAnonymous: false,
LastActivityDate: "2014-02-17T00:01:39.707",
Membership: {
$id: "3",
$type: "SPA01.EntityFramework.Membership, SPA01",
UserId: "dd59fcd1-9d88-4494-a37c-1c25155cb77d",
ApplicationId: "23042eba-1113-4e56-8ac6-4640120ecc6c",
Password: "sdfasdfsadfsadfsafasfae0dfzT64vo=",
PasswordFormat: 1,
PasswordSalt: "/CRUMPNf9+byEdPraeasfsaQJw==",
Email: "MyEmail#hotmail.com",
PasswordQuestion: "TR",
PasswordAnswer: "B4HOezQ/TYasdfasfasfgjz4oAOERhnc=",
IsApproved: true,
IsLockedOut: false,
CreateDate: "2014-01-04T05:18:18.063",
LastLoginDate: "2014-02-17T00:01:39.707",
LastPasswordChangedDate: "2014-01-12T21:58:30.497",
LastLockoutDate: "1754-01-01T00:00:00.000",
FailedPasswordAttemptCount: 0,
FailedPasswordAttemptWindowStart: "1754-01-01T00:00:00.000",
FailedPasswordAnswerAttemptCount: 0,
FailedPasswordAnswerAttemptWindowsStart: "1754-01-01T00:00:00.000",
Comment: null,
User: {
$ref: "2"
}
},
UserProfile: {
$id: "4",
$type: "SPA01.EntityFramework.UserProfile, SPA01",
UserId: "dd59fcd1-9d88-4494-a37c-1c25155cb77d",
FirstName: "Duane",
LastName: "Haworth",
User: {
$ref: "2"
}
},
Roles: [ ]
},
membership: {
$ref: "3"
},
userProfile: {
$ref: "4"
}
},
I'm creating a User Admin screen where I'm going to display the information from all three tables.
Can I do this while still using Breeze using JsonResultsAdapter or do I need to do something on the Entity Framework side first?
Thanks
Breeze supports this scenario (wrapping entities in an anonymous object) out of the box; no extra work required. See the lookup lists example, for instance. The Breeze client needs to have the metadata to handle the entities, but that's no problem if you're using EF and the EFContextProvider.

Resources