I have a Users table and a Groups table, when I retrieve a single user, I want to get a list of all the groups that user belongs to. I created a joins table named GroupUsers and it has userId and groupId on it, this is how I know that a user belongs to a group. Now, when I try to get the list of groups a user belongs to using the sequelize include on find, it only returns the first match, if the user belongs to various groups. How do I solve this?
Users controller
return models.Users
.find({
include: [{
model: models.Groups,
as: 'groups',
limit: null,
required: false
}],
where: { username }
})
Returns this:
{
"id": 1,
"username": "John",
"phone": "xxxxxxxx",
"email": "john#email.com",
"createdAt": "2017-07-16T20:14:04.744Z",
"updatedAt": "2017-07-16T20:14:04.744Z",
"groups": [
{
"id": 1,
"name": "Test Group",
"type": "Public",
"createdAt": "2017-07-16T20:13:18.392Z",
"updatedAt": "2017-07-16T20:13:18.392Z",
"GroupUsers": {
"userId": 1,
"groupId": 1,
"last_seen": null,
"createdAt": "2017-07-16T20:14:27.903Z",
"updatedAt": "2017-07-16T20:14:27.903Z"
}
}
]
}
Instead of this:
{
"id": 1,
"username": "John",
"phone": "xxxxxxxx",
"email": "john#email.com",
"createdAt": "2017-07-16T20:14:04.744Z",
"updatedAt": "2017-07-16T20:14:04.744Z",
"groups": [
{
"id": 1,
"name": "Test Group",
"type": "Public",
"createdAt": "2017-07-16T20:13:18.392Z",
"updatedAt": "2017-07-16T20:13:18.392Z",
"GroupUsers": {
"userId": 1,
"groupId": 1,
"last_seen": null,
"createdAt": "2017-07-16T20:14:27.903Z",
"updatedAt": "2017-07-16T20:14:27.903Z"
}
},
{
"id": 2,
"name": "Test Group 2",
"type": "Public",
"createdAt": "2017-07-16T20:13:18.392Z",
"updatedAt": "2017-07-16T20:13:18.392Z",
"GroupUsers": {
"userId": 1,
"groupId": 2,
"last_seen": null,
"createdAt": "2017-07-16T20:14:27.903Z",
"updatedAt": "2017-07-16T20:14:27.903Z"
}
}
]
}
I'm sure I'm doing something wrong somewhere I just don't know where, that same thing may also be the cause of sequelize including the joins table in the result: GroupUsers
It appears that in my associations, I did:
Users.belongsToMany(models.Groups, {
through: 'GroupUsers',
as: 'groups',
foreignKey: 'groupId'
});
Instead of :
Users.belongsToMany(models.Groups, {
through: 'GroupUsers',
as: 'groups',
foreignKey: 'userId'
});
Note the foreignKey attribute
And as for the GroupUsers object that is also returned, I removed that by doing:
include: [{
model: models.Groups,
as: 'groups',
attributes: ['id', 'name'],
through: { attributes: [] }
}]
Note the through key which has attributes set to an empty array.
Related
when my backend send a payload with value:
Object {
"__v": 0,
"_id": "621ef5eec33b5c6d9d184563",
"category": "621ef5e8c33b5c6d9d18455e",
"createdAt": "2022-03-02T04:43:26.834Z",
"description": "",
"name": "Hair and Nails",
"price": 50,
"updatedAt": "2022-03-02T04:43:26.834Z",
},
How to add this Object to my serviceReducer
const initialState = {
isLoading: false,
error: false,
serviceCategories: [], //! serviceCategories is a Array
};
first of all, I map serviceCategories and selected serviceCategories that I need
return {
...state,
serviceCategories: state.serviceCategories.map((serviceCateogory) => {
return serviceCateogory._id === action.payload.category
? serviceCateogory //! here How I to add that object to services of serviceCateogory
: serviceCateogory;
}),
// ),
};
this is Structure of serviceCategories:
[
Object {
"__v": 0,
"_id": "621ef5e8c33b5c6d9d18455e",
"createdAt": "2022-03-02T04:43:20.754Z",
"name": "Category1",
"services": Array [
Object {
"__v": 0,
"_id": "621ef5eec33b5c6d9d184563",
"category": "621ef5e8c33b5c6d9d18455e",
"createdAt": "2022-03-02T04:43:26.834Z",
"description": "",
"name": "Service1",
"price": 50,
"updatedAt": "2022-03-02T04:43:26.834Z",
},
Object {
"__v": 0,
"_id": "621ef7d1c33b5c6d9d1845b1",
"category": "621ef5e8c33b5c6d9d18455e",
"createdAt": "2022-03-02T04:51:29.262Z",
"description": "",
"name": "Service2",
"price": 50,
"updatedAt": "2022-03-02T04:51:29.262Z",
},
],
"updatedAt": "2022-03-02T05:08:35.520Z",
},
Object {
"__v": 0,
"_id": "621ef5e8c33b5c6d9d18455e",
"createdAt": "2022-03-02T04:43:20.754Z",
"name": "Category2",
....
]
You need to first findIndex of the specific category from the redux state and then append the service in it.
Like:
let categories=[...state.serviceCategories];
let catIndex=categories.findIndex((item)=>item._id===action.payload.category);
if(catIndex!=-1) categories[catIndex].services.push(object); // append object (service) as you wish.
state.serviceCategories=categories;
I need one help related to the sequelize and I am using postgres.
I want to group records in sequelize. Also the form and user value comes after populate or using include method of sequelize.
I have applied this code but it didn't work:-
{
group: ['formId', 'userId', 'responseFrom'],
include: [ { model: forms, as: 'form' }, { model: users, as: 'user' } ]
}
Here the name of table is formAnswers.
[{
"id": 21,
"formId": 1,
"userId": 123,
"formQuestionId": 2,
"answer": "8,5,6",
"responseFrom": "WAITING",
"createdAt": "2020-01-14T02:31:19.173Z",
"form": {
"id": 1,
"name": "Choose Group",
},
"user": {
"id": 123,
"fullName": "Test User",
"username": "test123",
}
},
{
"id": 22,
"formId": 1,
"userId": 123,
"formQuestionId": 1,
"answer": "3",
"responseFrom": "WAITING",
"createdAt": "2020-01-14T02:31:19.178Z",
"form": {
"id": 1,
"name": "Choose Group",
},
"user": {
"id": 123,
"fullName": "Test User",
"username": "test123",
}
}]
This is the sample record, there will be multiple records for each user.
I want to group the records by using formId and userId. Also you can consider responseFrom in group by. I have tried with group in sequelize but its not working.
I need only single record which have formId and userId same. If we are using the above data so the expected output will be:-
[{
"id": 22,
"formId": 1,
"userId": 123,
"formQuestionId": 1,
"responseFrom": "WAITING",
"createdAt": "2020-01-14T02:31:19.178Z",
"form": {
"id": 1,
"name": "Choose Group",
},
"user": {
"id": 123,
"fullName": "Test User",
"username": "test123",
}
}]
I need to apply pagination for this as well so please keep it in mind.
Possible solution: (not tested)
formAnswers.findAll({
attributes: [
sequelize.literal(`DISTINCT ON("form_question_responses"."formId","form_question_responses"."userId","form_question_responses"."responseFrom") 1`),
'id',
'formId',
'userId',
'responseFrom',
],
include: [
{ model: forms, as: 'form', attributes: ['id', 'name'] },
{ model: users, as: 'user', attributes: ['id', 'fullName', 'username'] }
],
// automatically order by as used DISTINCT ON - DISTINCT ON strictly orders based on columns provided
// order: [
// ['formId', 'ASC'],
// ['userId', 'ASC'],
// ],
offset: undefined, // for no offset
limit: 50,
})
I have a complex graphql object/type that contains complex fields where value is the pagination data. One of the fields called comments and it contains the comments pagination data. I want to use the optimistic-ui approach and manually add the new Comment, when the user creates it, to the comments field value before the server mutation execution, and in this way I expect to show the user the freshly created comment while the mutation is executing on the server.
I'm really wondering about the best way how to do that?
I tried manually create the pagination node and push it inside the original comments nodes however I received an error: TypeError: Cannot add property 2, object is not extensible
I tried to clone the original comments value to be able to modify it but nothing helps somehow.
So I'd like to interest in some way how I could handle this problem.
I'll appreciate any help/information
P.S. Here is the code examples
The whole source Article object
{
"__typename": "Article",
"id": "607559b181072e34ecf7af25",
"createdAt": "2021-04-13T08:43:29.846Z",
"liked": false,
"likes": 0,
"commentsThreadId": "607559b181072e34ecf7af24",
"comments": {
"__typename": "CommentsConnection",
"totalCount": 2,
"pageInfo": {
"__typename": "PageInfo",
"hasNextPage": false,
"startCursor": "NjA3NTY4N2Y4MTA3MmUzNGVjZjdhZjI5",
"endCursor": "NjA5ZTRlMmIyM2U5NmEzZGRjOTQwMTIz",
"hasPreviousPage": false,
"count": 2
},
"edges": [
{
"__typename": "CommentEdge",
"node": {
"__typename": "Comment",
"id": "6075687f81072e34ecf7af29",
"text": "Comments like this are just amazing. YavatarImgUrlou can write whatever you want and after that, you can check the result of this. It can have more than 3 lines",
"liked": false,
"likes": 0,
"createdAt": "2021-04-13T09:46:39.806Z",
"owner": {
"__typename": "UserBase",
"id": "60658c4632aaea36205cffa2",
"firstName": "David",
"lastName": null,
"username": "david1",
"numericId": "3321"
}
}
},
{
"__typename": "CommentEdge",
"node": {
"__typename": "Comment",
"id": "609e4e2b23e96a3ddc940123",
"text": "Some simple comment guys",
"liked": false,
"likes": 0,
"createdAt": "2021-05-14T10:17:15.057Z",
"owner": {
"__typename": "UserBase",
"id": "608156675ca92e56749d71fc",
"firstName": "Sviat",
"lastName": null,
"username": "sviat1",
"numericId": "9421"
}
}
}
]
},
"author": {
"__typename": "User",
"id": "60754dda81072e34ecf7af13",
"imageUrl": null,
"firstName": "John",
"lastName": "Peterson",
"username": "john1",
"numericId": "3659"
},
"topics": [
{
"__typename": "Topic",
"id": "60658c8c470f285c18652917",
"name": "libsep"
},
{
"__typename": "Topic",
"id": "60658c89521b0e5c18daf3d6",
"name": "huribu"
}
]
}
The code I used to update the comments field
const { getArticle: cachedArticle } = apolloClient.readQuery({
query: GET_ARTICLE_QUERY,
variables: {
// Provide any required variables here
id: article.id,
},
});
const newComment = {
__typename: "Comment",
id: "6075687f81072e34ecf7af29",
text: 'Shiny New Comment Text',
liked: false,
likes: 0,
createdAt: "2021-04-13T09:46:39.806Z",
owner: {
__typename: "UserBase",
id: "60658c4632aaea36205cffa2",
firstName: "David",
lastName: null,
username: "david1",
numericId: "3321",
},
};
// Tried to create the new object that allowed to modify
const newComments = { ...cachedArticle.comments };
// got an error at this stage
newComments.edges.push({
__typename: "CommentEdge",
node: newComment,
});
I am having some trouble sorting a nested object by its timestamp. I was hoping for some help...
This is what the object looks like and what I have so far...
useEffect(() => {
if (realtime.length) {
let unorderedmessage = realtime.concat(messages);
const orderedMessages = unorderedmessage
.slice()
.sort((a, b) => new Date(a.createdAt) - new Date(b.createdAt));
setMessages(orderedMessages);
}
}, [realtime]);
[
Object {
"_id": "a16edcb7-17e1-46ea-b8ce-5ec312d5eb6c",
"createdAt": 2020-04-23T01:51:48.000Z,
"index": 1,
"key": "cid-1710824786",
"receiver": Array [
"OUloNoRKdIeyhNFcAAB6VLrZ5yH2",
],
"text": "2–> Olivia to Mike",
"user": Object {
"_id": "lTONqS9O00PhkxwHD2EYs05EMwu2",
"avatar": "123",
},
},
Object {
"_id": "5ef28d42-6f7c-45eb-a5e1-59ca700f56b7",
"createdAt": 2020-04-23T02:01:52.000Z,
"index": 1,
"key": "cid-1710824786",
"receiver": Array [
"OUloNoRKdIeyhNFcAAB6VLrZ5yH2",
],
"text": "4–> Olivia to mike",
"user": Object {
"_id": "lTONqS9O00PhkxwHD2EYs05EMwu2",
"avatar": "123",
},
},
Object {
"_id": "1e07873f-f010-4e9d-be17-9bcb7793695b",
"createdAt": 2020-04-23T02:02:06.000Z,
"index": 1,
"key": "cid-1710824786",
"receiver": Array [
"lTONqS9O00PhkxwHD2EYs05EMwu2",
],
"text": "5–> mike to Olivia",
"user": Object {
"_id": "OUloNoRKdIeyhNFcAAB6VLrZ5yH2",
"avatar": "123",
},
},
Object {
"_id": "5fecafc3-c608-4156-b88c-f6c57e8e9977",
"createdAt": 2020-04-23T02:01:20.000Z,
"index": 1,
"key": "cid-1710824786",
"receiver": Array [
"OUloNoRKdIeyhNFcAAB6VLrZ5yH2",
],
"text": "3–> Olivia to Mike",
"user": Object {
"_id": "lTONqS9O00PhkxwHD2EYs05EMwu2",
"avatar": "123",
},
},
Object {
"_id": "fae07391-9968-432a-8a39-0c1be0d7e9ac",
"createdAt": 2020-04-23T01:51:41.000Z,
"index": 0,
"key": "cid-1710824786",
"receiver": Array [
"lTONqS9O00PhkxwHD2EYs05EMwu2",
],
"text": "1–> mike to Olivia",
"user": Object {
"_id": "OUloNoRKdIeyhNFcAAB6VLrZ5yH2",
"avatar": "123",
},
},
],
The messages are still coming in out of order so I am sure I am writing the sort function incorrectly. I am going through these tutorials and docs and it seems to be correct....
https://www.geeksforgeeks.org/sort-an-object-array-by-date-in-javascript/
https://flaviocopes.com/how-to-sort-array-by-date-javascript/
How to sort an array by a date property
I have also tried explicitly writing out the function like:
let unorderedmessage = realtime.concat(messages);
unorderedmessage.sort(function(a, b) {
return new Date(b.createdAt) - new Date(a.createdAt);
});
setMessages(unorderedmessage);
but still no luck. Can anyone see what I am doing wrong?
Works like a charm for me: https://playcode.io/583725/
Cannot be the issue in your Object variable definition?
You don't need to specify Object, this is enough:
const myNewObject = {firstKey: 'firstValue', secondKeys: 'secondValue'}
But if you do, you have to create it with new keyword:
const myNewObject = new Object {firstKey: 'firstValue', secondKeys: 'secondValue'}
Below is my object First step is to check the socialAuth array of objects and get the platformName which has the showStats value as false.
I have accomplished the step1 as below
var arrList2 = _.pluck(_.where(creatorObj.socialAuth, {'showStats': false}), "platformName");
['Twitter'] is the output of the arrList2
var creatorObj =
{
"_id": "55e5b32f3874c964cc3dfe2e",
"firstName": "xyz",
"lastName": "abc",
"socialStats": [
{
"reach": 205976,
"_id": "asdfasdfasdf",
"profileUrl": null,
"engagements": 126,
"platformName": "Twitter"
}
],
"socialAuth": [
{
"screenName": "abc",
"userId": "12341234",
"_id": "55e5b3573874c964cc3dfe33",
"showStats": false,
"platformName": "Twitter"
},
{
"channelTitle": "xyz",
"channelId": "sdfgsdfgsdfg",
"_id": "55e5a040991c1321a5b9bd79",
"showStats": true,
"platformName": "Youtube"
}
]
};
Second step is to check the above arrList2 with the sociaStats array and remove the value from it and print the object again.
I need help in this second step.
I need the resulting object as
var creatorObj =
{
"_id": "55e5b32f3874c964cc3dfe2e",
"firstName": "xyz",
"lastName": "abc",
"socialStats": [],
"socialAuth": [
{
"screenName": "abc",
"userId": "12341234",
"_id": "55e5b3573874c964cc3dfe33",
"showStats": false,
"platformName": "Twitter"
},
{
"channelTitle": "xyz",
"channelId": "sdfgsdfgsdfg",
"_id": "55e5a040991c1321a5b9bd79",
"showStats": true,
"platformName": "Youtube"
}
]
};
You need to use _.remove() to remove the elements from array based on your condition.
Demo
var creatorObj = {
"_id": "55e5b32f3874c964cc3dfe2e",
"firstName": "xyz",
"lastName": "abc",
"socialStats": [{
"reach": 205976,
"_id": "asdfasdfasdf",
"profileUrl": null,
"engagements": 126,
"platformName": "Twitter"
}],
"socialAuth": [{
"screenName": "abc",
"userId": "12341234",
"_id": "55e5b3573874c964cc3dfe33",
"showStats": false,
"platformName": "Twitter"
}, {
"channelTitle": "xyz",
"channelId": "sdfgsdfgsdfg",
"_id": "55e5a040991c1321a5b9bd79",
"showStats": true,
"platformName": "Youtube"
}]
};
var arrList2 = _.pluck(_.where(creatorObj.socialAuth, {
'showStats': false
}), "platformName");
creatorObj.socialStats = _.remove(creatorObj.socialStats, function(n) {
return !_.includes(arrList2, n.platformName);
});
console.log(creatorObj);
document.write(JSON.stringify(creatorObj));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>