knockout foreach computed value - object

I am trying to add a computed value to my viewModel object. And I am using foreach to create a table of rows. I am not able to get around this computed function.
I am trying to do this.
viewModel =
{
objectName: ko.observable([
{ value: "", triggerValue: "0"},
{ value: "", triggerValue: "1"},
{ value: "", triggerValue: "1"}
]),
};
viewModel.objectName().value= ko.computed(function() {
return this.objectName().triggerValue= "0" ? "Apple" : "Microsoft";
}, this);
I want the viewModel objectName output to look like
{value: "Apple", triggerValue: "0"},
{value: "Microsoft", triggerValue: "1"},
{value: "Microsoft", triggerValue: "1"}
Thanks.
KDK

Several mistakes going on here
you are using an observable instead of observableArray, technically an observable can store an array, but you are better off using an observableArray
you are trying to tie a computed to objectName().value, but object name is suppose to be an array so it would not have a value, it would ideally be like this objectName()[1].value.
This is not how to assign properties, ko.computed is not a replacement for a function, computed are for monitoring existing observales and and re calculating when a change is made in one of the monitored observables.
I would do something like this.
viewModel =
{
objectName: ko.observable([
{ value: setType(0), triggerValue: "0"},
{ value: setType(1), triggerValue: "1"},
{ value: setType(1), triggerValue: "1"}
]),
};
function setType(trigger){
return trigger = "0" ? "Apple" : "Microsoft"
}
or better yet
viewModel =
{
objectName: ko.observable([
setVal(0),
setVal(1),
setVal(1),
]),
};
function setVal(trigger){
return {value: (trigger = "0" ? "Apple" : "Microsoft"), triggerValue: trigger };
}

Related

ArangoDB Retrieve parent object based on multiple filters on children properties

I have a Person object as follows
{
name: 'John Doe'
properties:
[
{
name: 'eyeColor',
value: 'brown'
},
{
name: 'age',
value: 25
},
{
name: 'interest',
value: 'reading'
},
{
name: 'interest',
value: 'diving'
}
]
}
Now I want to be able to filter my object based on multiple properties. In pseudocode:
Return all people for which
there exists any p.property such that
p.property.propertyname == 'interest'
AND p.property.propertyvalue == 'reading'
AND there exists any p.property such that
p.property.propertyname == 'age'
AND p.property.propertyvalue < 30
What is the most concise and extensible (I want to be able to apply N of these filters) of doing this without having too many intermediate results?

How to return the results of a bulk insert?

How do I return the array of newly inserted documents? I want to perform a bulk insert from Java.
INSERT {
text: #text0,
createdAt: #createdAt0
} IN messages
LET result0 = { id: NEW._key, text: NEW.text, createdAt: NEW.createdAt }
INSERT {
text: #text1,
createdAt: #createdAt1
} IN messages
LET result1 = { id: NEW._key, text: NEW.text, createdAt: NEW.createdAt }
RETURN [result0, result1]
Is there a better way to collect the results from each insert, other than defining a new variable to keep the results in it?
This query should do what you want.
FOR d IN [
{text:#text0, createdAt: #createdAt0}, {text:#text1, createdAt: #createdAt1}
]
INSERT d INTO abc
RETURN {
id: NEW._id,
text: d.text,
createdAt: d.createdAt
}
An example response from the AQL is:
[
{
"id": "abc/21971344",
"text": "apple",
"createdAt": 1584107091
},
{
"id": "abc/21971345",
"text": "banana",
"createdAt": 1584108473
}
]
So long as the end user doesn't craft the AQL it should be fine, especially since you're using parameters.
If you ever used the product beyond testing, I'd definitely recommend looking at Foxx, as it gives you a layer of abstraction, hosted (relatively) within the database, which at the least stops consumers from having to execute AQL queries at all, rather they just communicate via REST endpoints.
PS. This query format also works:
FOR d IN #messages
INSERT d INTO abc
RETURN {
id: NEW._id,
text: d.text,
createdAt: d.createdAt
}
Where #messages is
"messages": [
{
"text": "apple",
"createdAt": 1584107091
},
{
"text": "banana",
"createdAt": 1584108473
}
]

Is it possible to convert an array of json objects to a sequelize query?

I'm receiving an array of JSON objects from the client and I need to dynamically convert it to a sequelize query
I tried using switch cases such as case 'and' will make object.other = [op.and] and so on. But it doesn't work.
I expect to receive something like this:
[
{
other: "",
column: "name",
value: "Kevin"
}
{
other: "and",
column: "id",
value: "10"
}
]
and it should convert to
Model.findAll({
where: {
[Op.and]: [{name : 'Kevin'},{id: 10}]
}
})

MongoDB push into nested array without using indices

I'm looking to $push something into a nested array, of which the parent array matches a simple property condition:
Here's how my document looks:
{
name: "Foo",
boardBucket: {
currentBoardId: 1234,
items: [ <- looking to push into `boardItems` of an `item` in this Array
{
boardId: 1234, <- that has `boardId: 1234`
boardItems: [ "barItem", "deyItem" ] <- Final Array I want to push to
}
]
}
}
So I'd like to push "fooItem" in boardItems of item that has boardId: 1234
Option 1: I can use dot notation and access by index
I can certainly do a $push by using dot.notation which uses the index of the item like so:
this.update({ '$push': {"boardBucket.items.0.boardItems": "fooItem" } });
But what if I don't know the index?
How can I push into boardItems of item with boardId: 1234 without using the indices (using the boardId instead)?
Note:
I'm using mongoose as the db driver
I'd like to avoid using mongoose's save() cause it tends to be buggy + it seems to keep a copy of the object locally which i'd like to avoid
Just direct update() mongo queries are what I'm after
I'd certainly like to avoid any type of whole-document fetching to perform this update as my documents are huge in size
I think this should do the trick:
this.update(
{"boardBucket.items": {$elemMatch: { boardId: "1234"}}},
{'$push': {"boardBucket.items.boardItems": "fooItem" }}
);
(Sorry for not sampling in the first place, was on a rush then)
db.myDb.insert({
name: "Foo",
boardBucket: {
currentBoardId: 1234,
items: [
{
boardId: 1234,
boardItems: [ "barItem", "deyItem" ]
},
{
boardId: 1235,
boardItems: [ "dontPushToThisOne" ]
}
]
}
});
db.myDb.insert({
name: "Foo2",
boardBucket: {
currentBoardId: 1236,
items: [
{
boardId: 1236,
boardItems: [ "dontPushToThisOne" ]
}
]
}
});
db.myDb.update(
{ "boardBucket.currentBoardId":1234,
"boardBucket.items.boardId":1234},
{ "$push" : {"boardBucket.items.$.boardItems":"fooItem"} }, {multi:1} );

DynamoDB : SET list_append not working using aws sdk

I need to append a string to a string set in a dynamodb table using the corresponding key. This is the Update expression I use to do updateItem :
var params = {
"TableName" : tableName,
"Key": {
"ID": {
S: "20000"
}
},
"UpdateExpression" : "SET #attrName = list_append(#attrName, :attrValue)",
"ExpressionAttributeNames" : {
"#attrName" : "entries"
},
"ExpressionAttributeValues" : {
":attrValue" : {"SS":["000989"]}
} };
This works when I do updateItem() using the aws cli. But when using aws-sdk in nodejs, I am getting the error:
Invalid UpdateExpression: Incorrect operand type for operator or function; operator or function: list_append, operand type: M\n
Any help?
Thanks
list_append can be read as a "concatenate" operation. You just give it two lists.
"UpdateExpression" : "SET #attrName = list_append(#attrName, :attrValue)",
"ExpressionAttributeNames" : {
"#attrName" : "entries"
},
"ExpressionAttributeValues" : {
":attrValue" : ["000989"]
}
It's worth remembering that lists (and maps) in DynamoDB are not typed and can store arbitrary data.
Side note: Armed with this knowledge, the documentation on appending to the beginning of the list now makes sense:
list_append (operand, operand)
This function evaluates to a list
with a new element added to it. You can append the new element to the
start or the end of the list by reversing the order of the operands.
There's an accepted answer on this question which helped me with part of this issue. However, we'll typically want to update lists with additional objects, not strings. For this, I found it useful to avoid using ExpressionAttributeNames if possible.
1) Make sure the value in your item in your DynamoDB table is a list.
2) Make sure you pass in a list of objects (even if you only have one), not a simple object
UpdateExpression: "set pObj.cObj= list_append(pObj.cObj, :obj)",
ExpressionAttributeValues: {
":obj": [
{myObject: {
property1: '',
property2: '',
property3: '',
}}
]
},
I thought I'd just throw this out there as another option for adding or appending an "object" to a list. It's a map being added an item to the list, and worked well for me:
var upsertExpr = (obj.comments == undefined) ? " :attrValue" : "list_append(#attrName, :attrValue)";
var params = {
TableName: 'tableName',
Key: {
'id': {'S': id},
},
UpdateExpression : "SET #attrName = " + upsertExpr,
ExpressionAttributeNames : {
"#attrName" : "comments"
},
ExpressionAttributeValues : {
":attrValue" : {
"L": [
{ "M" :
{
"comment": {"S": comment},
"vote": {"N": vote.toString()}
}
}
]
}
}
};
maybe this will help someone. i was struggling with updating a list and was getting the same error message as the original poster. i managed to solve my problem when i finally understood the documentation (see the Adding Elements To a List example here http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.ADD)
points to note are: 1) that the "list_append takes two lists as input, and appends the second list to the first." and 2) that ExpressionAttributeValues is a list! like this:
{
":vals": {
"L": [
{ "S": "Screwdriver" },
{"S": "Hacksaw" }
]
}
}
good luck!

Resources