Issue while updating nested data createEntityAdapter RTK query - javascript

I am working on the chat that is utilising RTK Query with entity adapters. We created nested normalised createEntityAdapter . I want to update the message key from onCacheEntryAdded, but not able to update nested object. I'm attaching the query endpoint code along with sample response.
RTK Query Endpoint
endpoints: builder => ({
getMessages: builder.query({
query: ({ orderId, userId, channel }) => {
return {
url: `/messages?orderId=${orderId}&userId=${userId}`,
method: 'GET',
}
},
transformResponse(response, meta, arg) {
return messagesAdapter.setAll(messagesAdapter.getInitialState(), [
{
id: `${arg.orderId}-${arg.userId}`,
isTyping: false,
channel: arg.channel,
orderId: arg.orderId,
messages: messagesAdapter.addMany(
messagesAdapter.getInitialState(),
response,
),
},
])
},
async onCacheEntryAdded(
arg,
{ updateCachedData, cacheDataLoaded, cacheEntryRemoved, cacheData },
) {
try {
await cacheDataLoaded
updateCachedData(draft => {
messagesAdapter.updateOne(draft, {
id: '62d529f60be7549be1f53df3-62d64eef37d10fea52e1ce72',
changes: {
messages: messagesAdapter.updateOne(
messagesAdapter.getInitialState(),
{
id: '62da7221bc0eb3a259fc2256',
changes: {
message: 'updated message',
},
},
),
},
})
})
} catch {
// no-op in case `cacheEntryRemoved` resolves before `cacheDataLoaded`,
// in which case `cacheDataLoaded` will throw
}
await cacheEntryRemoved
},
providesTags: (result, error, arg) => {
console.log('providesTags', result, error, arg)
return ['chat']
},
}),
}),
Sample response
{
"ids": [
"62d529f60be7549be1f53df3-62d64eef37d10fea52e1ce72"
],
"entities": {
"62d529f60be7549be1f53df3-62d64eef37d10fea52e1ce72": {
"id": "62d529f60be7549be1f53df3-62d64eef37d10fea52e1ce72",
"isTyping": false,
"channel": "62d7d9266599a9f0c3bcdaba",
"orderId": "62d529f60be7549be1f53df3",
"messages": {
"ids": [
"62da7221bc0eb3a259fc2256",
"62da724dbc0eb3a259fc2260",
"62da75559f7a23f89a0958d4",
"62da94e59f7a23f89a0958ed"
],
"entities": {
"62da7221bc0eb3a259fc2256": {
"order": "62d529f60be7549be1f53df3",
"alias": "Jacques82",
"sender": "62d7999d976791c65dd6eacd",
"senderRole": "ops",
"receiver": "62d64eef37d10fea52e1ce72",
"receiverRole": "student",
"receiverAlias": "Daniela_Jacobs0",
"message": "dsds",
"sentAt": "2022-07-22T09:47:13.000Z",
"id": "62da7221bc0eb3a259fc2256"
},
"62da724dbc0eb3a259fc2260": {
"order": "62d529f60be7549be1f53df3",
"alias": "Jacques82",
"sender": "62d7999d976791c65dd6eacd",
"senderRole": "ops",
"receiver": "62d64eef37d10fea52e1ce72",
"receiverRole": "student",
"receiverAlias": "Daniela_Jacobs0",
"message": "hello nm",
"sentAt": "2022-07-22T09:47:57.000Z",
"id": "62da724dbc0eb3a259fc2260"
},
"62da75559f7a23f89a0958d4": {
"order": "62d529f60be7549be1f53df3",
"alias": "Jacques82",
"sender": "62d7999d976791c65dd6eacd",
"senderRole": "ops",
"receiver": "62d64eef37d10fea52e1ce72",
"receiverRole": "student",
"receiverAlias": "Daniela_Jacobs0",
"message": "b",
"sentAt": "2022-07-22T10:00:53.000Z",
"id": "62da75559f7a23f89a0958d4"
},
"62da94e59f7a23f89a0958ed": {
"order": "62d529f60be7549be1f53df3",
"alias": "Jacques82",
"sender": "62d7999d976791c65dd6eacd",
"senderRole": "ops",
"receiver": "62d64eef37d10fea52e1ce72",
"receiverRole": "student",
"receiverAlias": "Daniela_Jacobs0",
"message": "hello there",
"sentAt": "2022-07-22T12:15:31.000Z",
"id": "62da94e59f7a23f89a0958ed"
}
}
}
}
}
}

Related

How to return single object (mongoose/mongoDB)

I have this data stored in database.
{
"_id": "62fa5aa25778ec97bc6ee231",
"user": "62f0eb5ebebd0f236abcaf9d",
"name": "Marketing Plan",
"columns": [
{
"name": "todo",
"_id": "62fa5aa25778ec97bc6ee233",
"tasks": [
{
"title": "Task Four testing 2",
"description": "This is task four",
"subtasks": [
{
"name": "wash dshes test",
"completed": false,
"_id": "62ff74bfe80b11ade2d34456"
},
{
"name": "do homework",
"completed": false,
"_id": "62ff74bfe80b11ade2d34457"
}
],
"_id": "62ff74bfe80b11ade2d34455"
}
]
},
{
"name": "doing",
"_id": "62fa5aa25778ec97bc6ee234",
"tasks": []
},
{
"name": "done",
"_id": "62fa5aa25778ec97bc6ee235",
"tasks": []
}
],
"__v":0
}
I want to be able to return a single object with the id equal to the req.params.id, in this case that would be 62ff74bfe80b11ade2d34455.
{
"title": "Task Four testing 2",
"description": "This is task four",
"subtasks": [
{
"name": "wash dshes test",
"completed": false,
"_id": "62ff74bfe80b11ade2d34456"
},
{
"name": "do homework",
"completed": false,
"_id": "62ff74bfe80b11ade2d34457"
}
],
"_id": "62ff74bfe80b11ade2d34455"
}
I researched stackoverflow and came across this potential solution: Mongoose retrieve one document from nested array which implemented the aggregate framework. But when I test this in postman, the request isn't made.
const getTask = asyncHandler(async (req, res) => {
const task = await Board.aggregate([
{
$match: {
"columns.tasks._id": req.params.id,
},
},
{
$project: {
columns: {
$first: {
$filter: {
input: "$columns.tasks",
cond: {
$eq: ["$$this._id", req.params.id],
},
},
},
},
},
},
{
$replaceRoot: {
newRoot: "$columns",
},
},
]);
});
Having an array inside an array complicates the query a bit, but here's one way to retrieve the data you want.
db.Board.aggregate([
{
$match: {
"columns.tasks._id": req.params.id
}
},
{"$unwind": "$columns"},
{
$match: {
"columns.tasks._id": req.params.id
}
},
{
"$project": {
"task": {
"$first": {
"$filter": {
"input": "$columns.tasks",
"cond": {"$eq": ["$$this._id", req.params.id]}
}
}
}
}
},
{"$replaceWith": "$task"}
])
Try it on mongoplayground.net. [The mongoplayground.net example uses "62ff74bfe80b11ade2d34455" rather than req.params.id.]

How To $pull From Deeply Nested Document (mongoose)

I need to delete a location object from the locations array. It is deeply nested. I followed mongoose documentation but my attempts didn't work:
lists = [{
"listName": "Test",
"_id": "8d55f0afe545a0178c320706",
"listId": "5fd9a3bef6c39b2f9c4df65b",
"date": "12/15/2020",
"dueDate": "2020-11-18",
"items": [
{
"itemNumber": 123,
"description": "item123",
"onHand": 60,
"_id": "13dd1f26ecd2baeb61b3b455",
"locations": [
{
"locationName": "loc1",
"count": 10,
"_id": "50a2c969465ba8010bd48977"
},
{
"locationName": "loc2",
"count": 20,
"_id": "51c2f1d25311dc8fabdbf604a59b"
},
{
"locationName": "Loc3",
"count": 30,
"_id": "7cb0c1f51a91c384846d65f8b2ae"
}
]
},
{more lists}
Attempt:
router.post("/lists/deleteLoc", (req, res) => {
const {
listId,
list_id,
item_id,
location_id
} = req.body;
List.updateOne({
"lists.listId": listId,
"lists._id": list_id
}, {
$pull: {
"lists.$.items": {
locations: {
$elemMatch: {
_id: location_id
})
.then(() => res.json({
msg: "location removed"
}))
.catch((err) => res.status(400).json({
msg: "Error: " + err
}));
});
If the request location_id was "7cb0c1f51a91c384846d65f8b2ae" it should delete the last location from the array. The desired result:
lists = [{
"listName": "Test",
"_id": "8d55f0afe545a0178c320706",
"listId": "5fd9a3bef6c39b2f9c4df65b",
"date": "12/15/2020",
"dueDate": "2020-11-18",
"items": [
{
"itemNumber": 123,
"description": "item123",
"onHand": 60,
"_id": "13dd1f26ecd2baeb61b3b455",
"locations": [
{
"locationName": "loc1",
"count": 10,
"_id": "50a2c969465ba8010bd48977"
},
{
"locationName": "loc2",
"count": 20,
"_id": "51c2f1d25311dc8fabdbf604a59b"
}
]
},
{more lists}
I've tried basically all variations of this, but none have worked.
I'm also not sure if making a router.post or an axios.post request for deletion is correct. Should this be axios.delete and router.delete?
I've tried this in one of my similar DB and worked!
List.updateOne({ "listId": yourListId },
{
'$pull': {
'items.$[item].locations': { "_id": yourLocationId }
}
}, {
"arrayFilters": [
{
"item._id": yourItemId
}
]
}, function (err) {
if (err) {
res.json(err)
} else {
res.json({ message: "Updated" })
}
})
}
You've to put the values that're inside your DB from the object that you want to delete.
So if you want to delete the object with
"locationname" : "Loc3"
You should use
var yourListId = "5fd9a3bef6c39b2f9c4df65b";
var yourItemId = "13dd1f26ecd2baeb61b3b455";
var yourLocationId = "7cb0c1f51a91c384846d65f8b2ae";
Try it out!

Sending rich message in Dialogflow fullfilment

I am trying to create a DialogFlow chatbot setting up my fullfilment with rich message but the payload that carry it never show up.
Here is the inline code I'm using:
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion, Payload} = require('dialogflow-fulfillment');
var answers = [];
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function fallback(agent) {
agent.add(`I didn't understand FULLFILMENT`);
agent.add(`I'm sorry, can you try again? FULLFILMENT`);
}
function answer1Handler(agent){
agent.add(`Intent answer1 called`);
const answer = agent.parameters.number;
answers.push(answer);
const payload = {
"text": "Trucmuche"/*,
"attachments": []*/
};
agent.add(new Payload(agent.SLACK, payload));
/*agent.add(
new Payload(agent.SLACK, payload, {rawPayload: true, sendAsMessage: true})
);*/
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Default Fallback Intent', fallback);
intentMap.set('answer1', answer1Handler);
agent.handleRequest(intentMap);
});
This is called when reaching "answer1" intent. It works well when my answer1Handler is only:
function answer1Handler(agent){
agent.add(`Intent answer1 called`);
}
I don't know what I missed I tried both to follow the official documentation on rich message as well as this response but none helped me create my rich responses.
However, when I add a the custom payload you can see above, it doesn't answer anymore and I get an error message in raw api response. Indeed, it wither gives an error:
{
"responseId": "49e306dc-c2a9-4667-ac67-60eb3692ce98-e15c53b8",
"queryResult": {
"queryText": "1",
"parameters": {
"number": 1
},
"allRequiredParamsPresent": true,
"outputContexts": [
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer2",
"lifespanCount": 5,
"parameters": {
"number.original": "1",
"number": 1
}
},
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer1",
"lifespanCount": 4,
"parameters": {
"number.original": "1",
"number": 1
}
}
],
"intent": {
"name": "projects/pollingagent-jnscpa/agent/intents/bea1536a-dede-4faf-ab44-2ba4f80e9c0f",
"displayName": "answer1"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 4993
},
"languageCode": "en"
},
"webhookStatus": {
"code": 4,
"message": "Webhook call failed. Error: DEADLINE_EXCEEDED."
},
"alternativeQueryResults": [
{
"queryText": "1",
"outputContexts": [
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer1",
"lifespanCount": 4,
"parameters": {
"number.original": "1",
"number": 1
}
},
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer2",
"lifespanCount": 3,
"parameters": {
"number.original": "1",
"number": 1
}
}
],
"languageCode": "en"
}
]
}
Or only gives back the first message as you can see in the raw API response:
{
"responseId": "b6bc8807-eca9-45e5-b25e-30e1b4142da7-e15c53b8",
"queryResult": {
"queryText": "1",
"parameters": {
"number": 1
},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
"Intent answer1 called"
]
}
}
],
"outputContexts": [
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer2",
"lifespanCount": 5,
"parameters": {
"number.original": "1",
"number": 1
}
},
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer1",
"lifespanCount": 4,
"parameters": {
"number.original": "1",
"number": 1
}
}
],
"intent": {
"name": "projects/pollingagent-jnscpa/agent/intents/bea1536a-dede-4faf-ab44-2ba4f80e9c0f",
"displayName": "answer1"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 217
},
"languageCode": "en"
},
"webhookStatus": {
"message": "Webhook execution successful"
},
"alternativeQueryResults": [
{
"queryText": "1",
"outputContexts": [
{
"name": "projects/pollingagent-jnscpa/agent/sessions/b6a5e9be-dd3e-7b54-3c4f-d942de297036/contexts/await_answer1",
"lifespanCount": 4
}
],
"languageCode": "en"
}
]
}
Consequently how can I send rich message within dialogflow fullfilment?

Sequelize where condition for multiple tables not working

While building Sequelize query unable to filter data from two tables with two different where conditions. Here I am adding some code...
Models:
//Task model
module.exports = function(sequelize, DataTypes) {
var Task = sequelize.define("Task", {
type: DataTypes.STRING(100),
start : DataTypes.DATE,
finish : DataTypes.DATE,
status : DataTypes.STRING(1),
}, {
classMethods: {
associate: function(models) {
Task.belongsTo(models.User, {
onDelete: "CASCADE",
foreignKey: {
allowNull: true
}
});
Task.hasOne(models.Evaluation);
Task.hasMany(models.Clarification);
}
}
});
return Task;
};
//Evaluation model
module.exports = function(sequelize, DataTypes) {
var Evaluation = sequelize.define("Evaluation", {
agent_id : DataTypes.INTEGER,
agent_name: DataTypes.STRING(100),
status: DataTypes.STRING(100),
}, {
classMethods: {
associate: function(models) {
Evaluation.belongsTo(models.Task, {
onDelete: "CASCADE",
foreignKey: {
allowNull: false
}
});
Evaluation.hasMany(models.Clarification);
}
}
});
return Evaluation;
};
//Clarification model
module.exports = function(sequelize, DataTypes) {
var Clarification = sequelize.define("Clarification", {
result : DataTypes.TEXT,
status : DataTypes.STRING(100),
comment : DataTypes.TEXT
}, {
classMethods: {
associate: function(models) {
Clarification.belongsTo(models.Task, {
onDelete: "CASCADE",
foreignKey: {
allowNull: false
}
});
Clarification.belongsTo(models.Evaluation, {
onDelete: "CASCADE",
foreignKey: {
allowNull: false
}
});
}
}
});
return Clarification;
};
I just added required code not exactly same.
Actually Using:
var filterobj = {
where: {
"UserId": { $ne: "NULL" }
},
include: [{
model: models.Evaluation,
attributes: ["id", "status","agent_name"],
where: {
"status": { $ne: "created" }
},
include: [{
model: models.EvalForm,
attributes: ["id", "name","LobId"],
include: [{
model: models.Lob,
attributes: ["id", "ClientId"]
},
{
model: models.FormDetails,
attributes: ["version", "status"]
}
]
}, {
model: models.Clarification,
attributes: ["id", "status"]
}],
required: true
},{
model: models.User,
attributes: ["name"]
}]
};
models.Task.findAll(filterobj).then(function (tasklist) {
// Doing some stuff for specific format
return res.send(tasklist);
}).catch(function (err) {
return res.send({ "error": { "code": 5000, "message": err.message } });
});
Response:
[
{
"id": 760,
"type": "clarification",
"start": "2017-07-12T14:30:52.000Z",
"finish": "2017-07-13T05:41:56.000Z",
"status": "A",
"UserId": 854,
"Evaluation": {
"id": 760,
"status": "completed",
"agent_name": "TestAgent1",
"EvalForm": {
"id": 5000008,
"name": "MobiPostpaid1",
"LobId": 26,
"Lob": {
"id": 26,
"ClientId": 1
},
"FormDetails": [
{
"version": 1,
"status": "A"
}
]
},
"Clarifications": [
{
"id": 70,
"status": "raised"
},
{
"id": 71,
"status": "esclate"
}
]
},
"User": {
"name": "pooja.s"
}
},
{
"id": 761,
"type": "clarification",
"start": "2017-07-12T14:30:52.000Z",
"finish": "2017-07-12T14:35:30.000Z",
"status": "A",
"UserId": 854,
"Evaluation": {
"id": 761,
"status": "assigned",
"agent_name": "TestAgent1",
"EvalForm": {
"id": 5000008,
"name": "MobiPostpaid1",
"LobId": 26,
"Lob": {
"id": 26,
"ClientId": 1
},
"FormDetails": [
{
"version": 1,
"status": "A"
}
]
},
"Clarifications": []
},
"User": {
"name": "pooja.s"
}
}
]
Expected Code(Not working)
var filterobj = {
where: {
"UserId": { $ne: "NULL" }
},
include: [{
model: models.Evaluation,
where: {
"status": { $in: ["assigned","completed"] }
},
attributes: ["id", "status","agent_name"],
include: [{
model: models.EvalForm,
attributes: ["id", "name","LobId"],
include: [{
model: models.Lob,
attributes: ["id", "ClientId"]
},
{
model: models.FormDetails,
attributes: ["version", "status"]
}
]
}, {
model: models.Clarification,
attributes: ["id", "status"]
}],
required: true
},{
model: models.User,
attributes: ["name"]
}, {
model: models.Clarification,
where: {
"status": { $in: ["raised"] }
}
attributes: ["id", "status"]
}]
};
models.Task.findAll(filterobj).then(function (tasklist) {
// Doing some stuff for specific format
return res.send(tasklist);
}).catch(function (err) {
return res.send({ "error": { "code": 5000, "message": err.message } });
});
Expected Response:
[
{
"id": 760,
"type": "clarification",
"start": "2017-07-12T14:30:52.000Z",
"finish": "2017-07-13T05:41:56.000Z",
"status": "A",
"UserId": 854,
"Evaluation": {
"id": 760,
"status": "completed",
"agent_name": "TestAgent1",
"EvalForm": {
"id": 5000008,
"name": "MobiPostpaid1",
"LobId": 26,
"Lob": {
"id": 26,
"ClientId": 1
},
"FormDetails": [
{
"version": 1,
"status": "A"
}
]
},
"Clarifications": [
{
"id": 70,
"status": "raised"
},
{
"id": 71,
"status": "esclate"
}
]
},
"User": {
"name": "pooja.s"
},
"Clarifications": [
{
"id": 70,
"status": "raised"
}
]
},
{
"id": 761,
"type": "clarification",
"start": "2017-07-12T14:30:52.000Z",
"finish": "2017-07-12T14:35:30.000Z",
"status": "A",
"UserId": 854,
"Evaluation": {
"id": 761,
"status": "assigned",
"agent_name": "TestAgent1",
"EvalForm": {
"id": 5000008,
"name": "MobiPostpaid1",
"LobId": 26,
"Lob": {
"id": 26,
"ClientId": 1
},
"FormDetails": [
{
"version": 1,
"status": "A"
}
]
},
"Clarifications": []
},
"User": {
"name": "pooja.s"
},
"Clarifications": []
}
]
I can include Clarification table inside Task and Evaluation tables I have that association. The problem with where condition. It is pulling all the records. I am expecting data from Clarification table with status raised. And from Evaluation table status with assigned and completed. Some where I saw code using OR operator.
A.findAll({
where: {
$or: [
{'$B.userId$' : 100},
{'$C.userId$' : 100}
]
},
include: [{
model: B,
required: false
}, {
model: C,
required: false
}]
});
But this is not working for me.

Documents are not deleted when using the Javascript APIs deleteByQuery()?

Using deleteByQuery() in the Javascript API I would like to delete some documents from an index called people.
It might be important to note that this is version 5.1 in AWS Elastic Search Service.
The index mapping looks like this:
"people": {
"mappings": {
"person": {
"properties": {
"name": {
"type": "string"
},
"parent_id": {
"type": "long"
},
"query": {
"properties": {
"match": {
"properties": {
"parent_id": {
"type": "long"
}
}
},
"term": {
"properties": {
"parent_id": {
"type": "long"
}
}
}
}
}
}
}
}
}
And a search query that is structured as follows:
query: {
term: {
parent_id: 1
}
}
Responds with:
"hits": {
"total": 1,
"max_score": 10.135444,
"hits": [
{
"_index": "people",
"_type": "person",
"_id": "AVp6EDRVm933W5mwl4O9",
"_score": 10.135444,
"_source": {
"name": "Bob",
"parent_id": 1
}
}
]
}
So then using the documentation for the JS API I have created the following:
const elasticsearch = require('elasticsearch')
function deletePeople (parentId) {
new elasticsearch
.Client({ host: 'es.host.domain' })
.deleteByQuery({
index: 'people',
type: 'person',
body: {
query: {
term: {
parent_id: parentId
}
}
}
}, function afterDeletingPeople (error, response) {
if (error) {
return console.log("deletePeople :: Error :: ", error);
}
else {
return console.log("deletePeople :: Response :: ", response);
}
});
};
deletePeople(1);
Which gives a response like:
info: deletePeople :: Response :: { _index: 'people',
_type: 'person',
_id: '_delete_by_query',
_version: 30,
_shards: { total: 2, successful: 1, failed: 0 },
created: false }
And that looks hopeful but no people are actually removed from the index. I tried to use match instead of term in the query but that does the same thing.
Could anyone suggest where I have gone wrong here with this as currently my function deletes no people? TIA!

Categories

Resources