how to avoid duplicate entries in akita store? - angular-akita

Before sending API request to insert I want to check the item is already exist in store or not, if not then only send the request to insert.
add(){
const item = {id: 4,name:'test1',description:'description'}
// here i want to check whether test1 already exist or not
this.store.add(item);
this.httpService.insert(item).subscribe(
result => {
this.messageService.handleSuccess('inserted');
this.store.updateId(id, result.id);
},
error => this.messageService.handleError('error on insert:', error)
);
can someone please help?

You can use the query:
add(){
const item = {id: 4,name:'test1',description:'description'}
if(query.hasEntity(4)) {
// exists
}
this.store.add(item);
this.httpService.insert(item).subscribe(
result => {
this.messageService.handleSuccess('inserted');
this.store.updateId(id, result.id);
},
error => this.messageService.handleError('error on insert:', error)
);

Related

changed object structure from item with object to array of objects in MongoDB shows error "An error occurred while deserializing"

I have changed the object structure from
{
id:"...",
name:"...",
url:"...",
studentAccess:{
"A":"....",
"B":"...",
},
ecosystemId:"..."
}
TO:
{
id:"...",
name:"...",
url:"...",
studentAccess:[
{
"X":"....",
"Y":"..."
},
{
"X":"....",
"Y":"..."
},
{
"X":"....",
"Y":"..."
},
],
ecosystemId:"..."
}
in API we get list of these objects based on ecosystemid or student access item "X", name or any field..calling like this in API
var acc = await _eco.FindByUser();
var query = await _db.CourseDocuments.FindAsync(w => w.EcosystemId == acc.Identifier);
after query executes i get this error pls help me i need to change structure anywhere after it changed in mongoDB?

v-model and passing a parameter to a rest patch api call

Very new to Vue2, so far so good but I hit a little snag and front end is not my forte.
The table(vue-tables-2) displays correctly what's in the database. I am passing an id in a function to determine what particular row to update but I also want to update the value of the checkbox in the database whenever I press it. How can I achieve that? Many thanks.
<v-client-table :data="tableData" :columns="columns" :options="options" >
<input type="checkbox" v-model="props.row.powerOff" #change="powerOff(props.row.id, props.row.powerOff)">
</v-client-table>
export default {
data() {
return {
columns: ['id', 'name', 'location.address', 'status', 'payment', 'powerOff'],
tableData: []
}
},
created() {
HTTP.get('test').then( response => {this.tableData = response.data;})
.catch( error => {});
},
methods: {
powerOff(id, currentPowerOff) {
var testURL = 'test/' + id
HTTP.patch(testURL, {id, currentPowerOff})//
.then( response => {})
.catch( error => {console.log(error); });
}
}
}
It seems that changing from v-click:on to #change fixed my issue. Reading a little bit more about it, click event is run before v-model has updated the value, while #change does it afterwards. Thank you !

Mongoose remove one object from array of array

I have Mongoose schema like this:
{
......
project: [
{
Name: String,
Criteria:[
{
criteriaName:String,
}
]
}
]
......
}
And I want to remove one of the objects of criteria array which is in the array of project based on the object id
I tried the code following
criteria.findOneAndUpdate({
"_id": uid,
},{ $pull: { "project.Criteria": { _id: cid } } }, (err) => {
......
}
However this cannot work, it said "Cannot use the part (Criteria) of (project.Criteria) to traverse the element"
Do you need to do it in one query to the database? If not, the following solution may work for you:
criteria.findOne({ _id: uid })
.then((obj) => {
// Filter out the criteria you wanted to remove
obj.project.Criteria = obj.project.Criteria.filter(c => c._id !== cid);
// Save the updated object to the database
return obj.save();
})
.then((updatedObj) => {
// This is the updated object
})
.catch((err) => {
// Handle error
});
Sorry if the .then/.catch is confusing. I can rewrite with callbacks if necessary, but I think this looks a lot cleaner. Hope this helps!

How to identify unique users with Diagflow

I am trying to make an assistant app and was using the cloud firestore service of firebase to send the response back to my app using webhook as fulfilment. I have used 'session' parameter in request JSON according to this documentation and sending fulfilmentText as response to the user. But whenever user launches the app, a new session is created which I don't want. I simply want, just a single entry for each user in my database so how to achieve that using dialogflow.
In Alexa Skill, we have deviceId as parameter by which we can uniquely identify the user irrespective of the session id but is there any parameter in the dialogflow request JSON. If not, then how to achieve this task without it.
The request JSON I am getting from Dialogflow has a userID in it, so can I use the userId or should I go with userStorage provided the userStorage parameter is not available in the request JSON.
request.body.originalDetectIntentRequest { source: 'google', version: '2', payload: { surface: { capabilities: [Object] },
inputs: [ [Object] ],
user:
{ locale: 'en-US',
userId: 'ABwppHG5OfRf2qquWWjI-Uy-MwfiE1DQlCCeoDrGhG8b0fHVg7GsPmaKehtxAcP-_ycf_9IQVtUISgfKhZzawL7spA' },
conversation:
{ conversationId: '1528790005269',
type: 'ACTIVE',
conversationToken: '["generate-number-followup"]' },
availableSurfaces: [ [Object] ] } }
EDIT : Thank You #Prisoner for the answer but I am unable to send the random ID generated in the response and set in in the payload. Below is the code where I am generating the uuid and storing it in firestore. What I am doing wrong in the below code due to which new uuid is generated for returning user and therefore response is shown as No document found in the database. I suppose I am not sending uuid appropriately. Please help.
exports.webhook = functions.https.onRequest((request, response) => {
console.log("request.body.queryResult.parameters", request.body.queryResult.parameters);
console.log("request.body.originalDetectIntentRequest.payload", request.body.originalDetectIntentRequest.payload);
let userStorage = request.body.originalDetectIntentRequest.payload.user.userStorage || {};
let userId;
console.log("userStorage", userStorage);
if (userId in userStorage) {
userId = userStorage.userId;
} else {
var uuid = require('uuid/v4');
userId = uuid();
userStorage.userId = userId
}
console.log("userID", userId);
switch (request.body.queryResult.action) {
case 'FeedbackAction': {
let params = request.body.queryResult.parameters;
firestore.collection('users').doc(userId).set(params)
.then(() => {
response.send({
'fulfillmentText' : `Thank You for visiting our ${params.resortLocation} hotel branch and giving us ${params.rating} and your comment as ${params.comments}.` ,
'payload': {
'google': {
'userStorage': userStorage
}
}
});
return console.log("resort location", params.resortLocation);
})
.catch((e => {
console.log('error: ', e);
response.send({
'fulfillmentText' : `something went wrong when writing to database`,
'payload': {
'google': {
'userStorage': userStorage
}
}
});
}))
break;
}
case 'countFeedbacks':{
var docRef = firestore.collection('users').doc(userId);
docRef.get().then(doc => {
if (doc.exists) {
// console.log("Document data:", doc.data());
var dat = doc.data();
response.send({
'fulfillmentText' : `You have given feedback for ${dat.resortLocation} and rating as ${dat.rating}`,
'payload': {
'google': {
'userStorage': userStorage
}
}
});
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
response.send({
'fulfillmentText' : `No feedback found in our database`,
'payload': {
'google': {
'userStorage': userStorage
}
}
});
}
return console.log("userStorage_then_wala", userStorage);
}).catch((e => {
console.log("Error getting document:", error);
response.send({
'fulfillmentText' : `something went wrong while reading from the database`,
'payload': {
'google': {
'userStorage': userStorage
}
}
})
}));
break;
}
You have a couple of options, depending on your exact needs.
Simple: userStorage
Google provides a userStorage object which is persisted across conversations when it can identify a user. This lets you store your own identifier when you need to track when a user returns.
The easiest way to do this is to check the userStorage object for the identifier when your webhook is called. If it doesn't exist, create one using something like a v4 UUID and save it in the userStorage object.
If you are using the actions-on-google library, the code might look something like this:
let userId;
// if a value for userID exists un user storage, it's a returning user so we can
// just read the value and use it. If a value for userId does not exist in user storage,
// it's a new user, so we need to generate a new ID and save it in user storage.
if (userId in conv.user.storage) {
userId = conv.user.storage.userId;
} else {
// Uses the "uuid" package. You can get this with "npm install --save uuid"
var uuid = require('uuid/v4');
userId = uuid();
conv.user.storage.userId = userId
}
If you are using the dialogflow library, you can use the above, but you'll need this line first:
let conv = agent.conv();
If you're using the multivocal library, it does all of the above for you and will provide a UserID in the environment under the path User/Id.
If you're handling the JSON directly, and you are using the Dialogflow v2 protocol, you can get the userStorage object by examining originalDetectIntentRequest.payload.user.userStorage in the JSON request object. You'll set the payload.google.userStorage object in the JSON response. The code is similar to the above and might look something like this:
let userStorage = body.originalDetectIntentRequest.payload.user.userStorage || {};
let userId;
// if a value for userID exists un user storage, it's a returning user so we can
// just read the value and use it. If a value for userId does not exist in user storage,
// it's a new user, so we need to generate a new ID and save it in user storage.
if (userId in userStorage) {
userId = userStorage.userId;
} else {
// Uses the "uuid" package. You can get this with "npm install --save uuid"
var uuid = require('uuid/v4');
userId = uuid();
userStorage.userId = userId
}
// ... Do stuff with the userID
// Make sure you include the userStorage as part of the response
var responseBody = {
payload: {
google: {
userStorage: JSON.stringify(userStorage),
// ...
}
}
};
Note the first line of the code - if userStorage doesn't exist, use an empty object. It won't exist until you send a response that includes storing something in it for the first time, which will happen in the last few lines of this code.
Advanced: Account Linking
You can request users to sign in to your Action using Google Sign In. This can be done just using voice for the simplest of cases and would only interrupt the flow the first time.
After this, your Action is given a JWT which contains their Google ID which you can use as their identifier.
If you're using the actions-on-google library, you can get the ID from the decoded JWT with a line such as:
const userId = conv.user.profile.payload.sub;
In the multivocal library, the ID from the decoded JWT is available in the environment under the path User/Profile/sub
Deprecated: Anonymous User ID
You'll see some answers here on StackOverflow that reference an Anonymous User ID. Google has deprecated this identifier, which was not always a reliable way to verify returning users, and will be removing it 1 Jun 2019.
This code is currently still being sent, but this will be removed starting 1 Jun 2019.

Mongoose create multiple objects in a array with partial success

There's a method Model#create in a Mongoose to which I can send an array of objects.
var items = [{id: 1},{id: 2},{id: 3},{id: 4}];
Model.create(array, function (err, succededItems) {
...
});
Everything works fine except behavior when some of the objects which I try to create failed to be saved. In this scenario in err object I get, there're details about first object which has been failed, and in succededItems I get an array of the objects which have been saved.
I doubt is it possible to get in err or other way, an array which objects failed to save and reason, why did this happen?
Thank you in advance.
Unfortunately Mongoose returns only the first error, so your best option would be to use a combination of promises :
Promise
.all( items.map( item => {
return Model.create( item )
.catch( error => ( { error } ) )
}) )
.then( items => {
items.forEach( item => {
if ( item.error ) {
console.log( "Item has failed with error", item.error );
} else {
console.log( "Item created successfully" );
}
} );
} );