rule engine function inside Meteor bindEnvironment losing its this object - javascript

var process_request_rule = [
{
"name": "rule-name",
"condition": Meteor.bindEnvironment(function (R) {
R.when(this.request.type == 'some-type');
})
}];
In the above code, this.request was getting undefined as this was pointing to Meteor object not to the function object. After researching got to know that using arrow functions might resolve the issue. Tried using that as shown below.
var process_request_rule = [
{
"name": "rule-name",
"condition": Meteor.bindEnvironment((R) => {
R.when(this.request.type == 'some-type');
})
}];
Still no luck, Please help me binding this object

You can either drop using Meteor.bindEnvironment or just use second argument passed to condition callback — it is the same as supposed this. https://github.com/mithunsatheesh/node-rules/blob/master/lib/node-rules.js#L94
Something like this:
var process_request_rule = [
{
"name": "rule-name",
"condition": Meteor.bindEnvironment(function(R, session) {
R.when(session.request.type == 'some-type');
})
}];

Related

My js code is not detecting an empty object

I'm not a complete beginner but that one is blocking me and my colleagues.
I have an application that is making calls with an empty body to my CRM which in turns responds with a 400 bad request exception.
I'm logging calls on datadog and I can see that the body is indeed empty despite my attempts to avoid making the call when that is the case.
Can you help? Do you have any ideas?
My code before calling the CRM repository method:
if (!isEmpty(personDto)) {
response = {
status: response.status.concat(`Person has been updated : ${JSON.stringify(personDto)}`),
personDto: personDto,
};
await this.pipedriveRepository.updatePerson(body.current.id, personDto);
} else {
response = {
status: response.status.concat(`Person has not changed and no update were made`),
personDto: personDto,
};
}
return response;
I'm using lodash isEmpty.
However, the method updatePerson is beeing called even when an object is empty, but only in production, not locally when I artificially pass an empty object.
async updatePerson(id: number, person: IPipedrivePersonDto): Promise < PipedrivePerson > {
const personApi = new this.pipeDriveClient.PersonsApi();
if (isEmpty(person) || Object.keys(person).length === 0) {
throw new Error(`Can't update a person with no body: ` + JSON.stringify(person));
}
try {
const {
data
} = (await personApi.updatePerson(id, person)) as PersonResponse;
return data;
} catch (e) {
if ((e as PipedriveResponseException).context.status === 400) {
return person as PipedrivePerson;
}
throw e;
}
}
Here I make the verification again and no error is thrown. However a calls to my CRM pipedrive is made and an empty body is logged on datadog.
opts and person are empty
{
"id": "AQAAAYOxHSvXy25ofAAAAA4SFM3WkFBQldILXNoZVMxU2R3QUI",
"content": {
"timestamp": "2022-10-07T06:23:42.551Z",
"tags": [
"service:growth",
"filename:app.log",
"sourcecategory:sourcecode",
"source:nodejs",
"buildpackversion:dev",
"dyno:web.1",
"dynotype:web",
"env:prod",
"version:1.0.0"
],
"host": "24f45b35-3ea7-487f-9c25-2372d17ceb",
"service": "growth",
"message": "POST /hooks/pipedrive/persons/updated",
"attributes": {
"timestamp": "2022-10-07 06:23:42",
"dd": {
"service": "growth"
},
"time": "2022-10-07T06:23:42.551Z",
"response": {
"body": "Person data has been cleant\r\nNo new email to validate\r\nPerson already has a valid email address\r\nPerson has been updated : {}",
"status": 201
},
"level": "info"
}
}
}
I'm wondering if there's not a subtle thing about javascript I am not understanding there.
Since I'm double checking with Object.keys, it should not be a lodash issue.
What can I do now? I'm running out of ideas, already tried all basic stuff.
The object is probably not empty. There are countless possible causes for a prop not being included after calling JSON.stringify.
Check for private properties on your dto class. Or a custom toJSON function.
Try logging not only the stringified object, but the object itself with a console.log.
class Person {
#privateProp = 1;
}
console.log(new Person()); // => { #privateProp: 1 }
console.log(JSON.stringify(new Person())); // => {}

How to do this: obj[i].["name of thing in object"]

I tried to work it out and ask who I could but no one gave me an answer that would work. can anyone advise me?
obj[i].["name of thing in object"]
this is array:
[
{
"name": "DISBOARD#2760",
"id": "3020508723832240"
},
{
"name": "Gumernus#0122",
"id": "7814540349956106"
}
]
Assuming your object looks a bit like
let obj = [
{ nameOfThingInObject: 'first'},
{ nameOfThingInObject: 'second'}
];
To retrieve the nameOfThingInObject you can do two things:
Use . to access the property
Use [] to access the property
Your example in the question seems to try both, which will result in an error. To retrieve the value, you can thus do:
let firstMethod = obj[0].nameOfThingInObject;
let secondMethod = obj[0]['nameOfThingInObject'];

Filter Array Using Partial String Match in Javascript

I have an array of objects where the value I need to filter on is buried in a long string. Array looks like:
{
"data": {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}",
"partnerId": 1
}
},
So if I wanted to grab all the partnerId objects where value includes parent_sku how would I do that?
console.log(data.value.includes('parent_sku') returns cannot read property 'includes' of null.
EDIT:
Didn't think this mattered, but judging by responses, seems it does. Here's the full response object:
Response body: {
"data": {
"configurationByCode": [
{
"data": {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}",
"partnerId": 1
}
}
I'm passing that into a re-usable function for filtering arrays:
const parentSkuPartners = filterArray(res.body.data.configurationByCode, 'parent_sku');
Function:
function filterArray(array, filterList) {
const newList = [];
for (let i = 0; i < array.length; i += 1) {
console.log('LOG', array[i].data.value.includes('parent_sku');
}
}
The problem is somewhere else. The code you've tried should work to find if a value contains a string – I've added it the snippet below and you'll see it works.
The issue is how you are accessing data and data.value. The error message clearly states that it believes that data.value is null. We would need to see the code around it to be able to figure out what the problem is. Try just logging to console the value of data before you run the includes function.
const data = {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}", "partnerId": 1
};
console.log('includes?', data.value.includes('parent_sku'));
You can use data.value.includes('parent_sku') as you have suggested. The issue here is that your object is nested inside an unnamed object.
try:
"data": {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}",
"partnerId": 1
}
The problem was some of the values for value were null. Adding an extra conditional fixed it:
if (array[i].data.value !== null) {
Use lodash includes, and lodash filter like
let configurationByCode = [{
data: {
value: {
cols:["parent_sku"],
label:"Style",
description:"Enter Style.",
placeholderText:"Style 10110120103"
},
"partnerId": 1
}
}, {
data: {
value: {
cols:["nothing"],
label:"Style",
description:"Enter Style.",
placeholderText:"Style 10110120103"
},
"partnerId": 2
}
}];
let wantedData = _.filter(configurationByCode, (config) => {
return _.includes(config.data.value.cols, 'parent_sku');
});
console.log( wantedData );
https://jsfiddle.net/76cndsp2/

how can i return the values from one specific object?

I am running a JSON server to create a simple login system. The data from the server looks like this:
{
"users": [
{
"name": "user1",
"password": "pass1",
"email": "useer1#user.com",
"id": 2,
"details": {
"first_name": "user1_1",
"last_name": "user1_2",
"gender": "male",
"pic": "",
"about": "fnbewhbdwie"
}
},
{
"name": "user2",
"password": "pass2",
"email": "user2#user.com",
"details": {
"first_name": "user2_1",
"last_name": "user2_2",
"gender": "male",
"pic": "",
"about": "cjkdbvcwvebxcnoewbvcu"
},
"id": 4
}
]
}
I have created a function to check if the name and password match from the user input, and if the condition is true I want to run another function that will return only the details of the object that have the name and password from the user input.
I have tried the find() method but it returns the details for the first object only
async getAcc() {
const {data} = await Axios
.get(`${BASE_URL}users`)
data.forEach(({name, password}) => {
if(this.nameInput.value === name && this.passInput.value === password){
showAcc();
}
else {
return false
}
}
)
function showAcc() {
let result = data.find(a => a.details)
console.log(result)
}
}
Putting aside the obvious problem with the user/pwd on the response, as mentioned on comments, I believe that what is wrong here is this:
First, your data is an array of objects.
So, by definition, 'find' will return the first entry that the lamba function successfully satisfies. In this case, you are passing the array into the find and saying, give me the first details object you find. It is doing the right thing.
I believe that your problem is on the forEach. Since you added name and pwd as parameters , it is only picking those properties for each item on the array. Try and change it to something like
.forEach(item => {,
which will send into the lamba function the complete object. Then, inside the method you will need to modify and use
if(this.nameInput.value === item.name
Finally, inside your if statement, you'll be able to even simplify your showAcc by sending the "details" property straight into the method like:
showAcc(item.details);
and
function showAcc(details) {
console.log(details);
}
Would be better if you had a sample we could edit , but I think this should work.
Good luck
I'd use the lodash filter method instead of find method.
Something like: _.filter(data, { 'name': 'user2', 'password': 'pass2' });
It should get you all the objects that match your criteria passed in the argument object as shown above.
WebDever may have pointed you to a better solution. I'll just point out my observation, which directly explains why you fail to print all the answers.
I don't know anything about any of the technology used, but it seems that the problem has to be the return value (or lack thereof) of the code block inside the forEach. Just showing the result, it appears, should in and of itself have no side effect in terms of stopping the iteration. So the key thing that happens when you first find a match is that you don't return 'false'. Up to that point, you've always been returning 'false'.
So my guess is that when you find a match, you're returning the result of the last expression rather than 'false', and that return value causes the iteration to stop. So change the code within the foreach to:
if(this.nameInput.value === name && this.passInput.value === password){
showAcc();
}
return false

Couchdb retrieving documents in array

The following document is a small example which is stored in CouchDB.
{
"_id": "Test4",
"referenceName": "refA",
"positions": {
"A": 422,
"B": 5442
},
"properties": [
{
"tId": "ARQ3TPR7",
"pos": 4609,
"zIds": [
"z0003674",
"z0008150",
"z0016020",
"z0016021"
]
}
],
...
}
The below map function does not work and I don't know how to fix it. I got Error: compilation_error Expression does not eval to a function. I would like to retrieve _id, referenceName and positions.
{
"_id": "_design/doc",
"views": {
"by_zIds": {
"map": "function(doc) {
for (var i in properties {
var d = doc.properties[i];
for (var x in d.zIds){
emit(d.zIds[x], doc);
}
}
}"
}
},
"language": "javascript"
}
How is it possible to fix the above map function in order to use the view like /dbname/_design/doc/_view/by_zIds?key="z0016021"?
There is a ) missing after properties in your map function. There might be other typos. I would suggest that you write your map functions in an editor with syntax highlighting and them locally to catch those kinds of errors early.
EDIT: There are several other problems with your map function, all of which can be found with unit testing and/or debugging. This should work, but I haven't tested it:
function(doc) {
for (var d in doc.properties) {
for (var x in d.zIds) {
emit(x, doc);
}
}
}
I solved it in the following way, but I am not sure whether it is the best way
function(doc) {
for (var i in doc.properties) {
for (var x in doc.properties[i].zIds) {
emit(doc.properties[i].zIds[x], doc);
}
}
}
Is it possible to improve?

Categories

Resources