node v7.7.1
mongodb: 2.2.33,
mongoose: 4.13.7
Hello all,
i'm having this unexpected behaviour when trying to update a document with multiple pull request based on matching criterias. here is what i mean
my document schma looks like this
{
"_id": "5a1c0c37d1c8b6323860dfd0",
"ID": "1511781786844",
"main": {
"_id": "5a3c37bfc065e86a5c593967",
"plan": [
{
"field1": 1,
"field2": 1,
"_id": "5a3c30dfa479bb4b5887e56e",
"child": []
},
{
"field1": 1,
"field2": 2,
"_id": "5a3c30e1a479bb4b5887e5c",
"child": []
},
{
"field1": 1,
"field2": 3,
"_id": "5a3c37bfc065e86a5c593968",
"child": []
},
{
"field1": 1,
"field2": 4,
"_id": "5a3c37bfc065e86a5c593655",
"child": []
},
{
"field1": 1,
"field2": 5,
"_id": "5a3c30dfa479bb4b5887e56f",
"child": []
},
{
"field1": 1,
"field2": 6,
"_id": "5a3c30e1a479bb4b6887e545",
"child": []
},
{
"field1": 1,
"field2": 7,
"_id": "5a3c37bfc065e86a5c5939658",
"child": []
},
{
"field1": 2,
"field2": 2,
"_id": "5a3c37bfc065e86a5c593963",
"child": []
},
]
},
...
....
}
and this is my code to update the document:
Schema.findOne({ID: data.ID})
.then(function(doc) {
var array = doc.main.plan;
for (i = 0; i < array.length; i++) {
if ( array[i].field1=== 1 )) {
var id = array[i]._id;
console.log('pulling');
doc.pull( { _id: id });
}
}
doc.save().then(function(doc) {
console.log('saving');
// console.log(doc);
if (doc && doc.docID) {
return { success: true };
} else {
return { success: false, error: 'unknownError'}
}
})
}
now the issue is let's say my array has 7 objects that matches the test (array[i].theField === parseInt(updFields.theField)), when i run this and check the logs i see that it will basically pull half of the objects and do a save.
so i would get
pulling
pulling
pulling
pulling
save.
and then i have to run the code for the remaining 3 objects in the array and get
pulling
pulling
saving
so i have to run it a third time to completely clear the array.
need help get this working
thank you
So i created a little workaround by doing a recursive function to pull all with only one click using lodash functions. not pretty but it does the job.
const delObjArray = (doc, cond) => {
const checkField = cond.field;
const checkVal = cond.value;
_.forEach(doc, (value) => {
if (value && value[checkField] === checkVal) {
doc.pull({ _id: value._id });
}
});
const isFound = _.some(doc, { [checkField]: checkVal });
if (isFound) {
delObjArray(doc, cond);
} else {
return true;
}
return true;
};
Related
I need your opinion in this situation:
I get from API with this function:
getRS(
idProject: string
): Observable<ResponseModel<RSModel>> {
return this.http.get<ResponseModel<RSModel>>(
ApiUrlsConfig.getRS(
idProject
)
);
}
this response:
{
"data": [
{
"id": "id1",
"state": 1,
"note": null
},
{
"id": "id1",
"state": 2,
"note": "Reason 1"
},
{
"id": "id2",
"state": 2,
"note": "Reason updated3",
}
],
"result": null
}
I need to use filter in this response because I should be get the last state for each id. For example, I want to display state 2 in item with id: id1. For this I want to use filter. The problem is because I can't use filter on it, I don't understand why.
I tried to write this code:
#Input() set jobId(jobId: string) {
this.optionsService
.getRS(
this.idProject
)
.pipe()
.subscribe((res) => {
let resId = res.filter((aaa)=>{
if(aaa.id === jobId){
res.slice(-1)[0].id
}
}
)
});
}
Not function.
Please can you share with me any idea?
Thank you
Try this logic:
Loop backwards throw it.
Loop backwards over index to the start.
Splice duplicates.
let response = {
"data": [
{
"id": "id1",
"state": 1,
"note": null
},
{
"id": "id1",
"state": 2,
"note": "Reason 1"
},
{
"id": "id2",
"state": 2,
"note": "Reason updated3"
}
],
"result": null
}
let data = response.data;
for (let i = data.length - 1; i >= 0; i--) {
for (let j = i - 1; j >= 0; j--) {
if (data[i].id === data[j].id) {
data.splice(j, 1);
j++;
}
}
};
console.log(data);
try this:
if(aaa.id == jobId){
return res.slice(-1)[0].id
}
I'm trying to sort the dates from this external API in my latestResults array by latest on top to oldest on bottom but can't seem to figure out how.
Right now they're displayed with the oldest date first and it's working fine, but it's in the wrong order for me.
I tried using result in latestResults.reverse() but that just reverses the 7 items currently in the array.
HTML:
<div v-for="result in latestResults" v-bind:key="result.latestResults">
<small">{{ result.utcDate }}</small>
</div>
Script:
<script>
import api from '../api'
export default {
data () {
return {
latestResults: [],
limit: 7,
busy: false,
loader: false,
}
},
methods: {
loadMore() {
this.loader = true;
this.busy = true;
api.get('competitions/PL/matches?status=FINISHED')
.then(response => { const append = response.data.matches.slice(
this.latestResults.length,
this.latestResults.length + this.limit,
this.latestResults.sort((b, a) => {
return new Date(b.utcDate) - new Date(a.utcDate);
})
);
setTimeout(() => {
this.latestResults = this.latestResults.concat(append);
this.busy = false;
this.loader = false;
}, 500);
});
}
},
created() {
this.loadMore();
}
}
</script>
The JSON where I'm getting matches like this that has utcDate:
{
"count": 205,
"filters": {
"status": [
"FINISHED"
]
},
"competition": {
"id": 2021,
"area": {
"id": 2072,
"name": "England"
},
"name": "Premier League",
"code": "PL",
"plan": "TIER_ONE",
"lastUpdated": "2021-02-01T16:20:10Z"
},
"matches": [
{
"id": 303759,
"season": {
"id": 619,
"startDate": "2020-09-12",
"endDate": "2021-05-23",
"currentMatchday": 22
},
"utcDate": "2020-09-12T11:30:00Z",
"status": "FINISHED",
"matchday": 1,
"stage": "REGULAR_SEASON",
"group": "Regular Season",
"lastUpdated": "2020-09-13T00:08:13Z",
"odds": {
"msg": "Activate Odds-Package in User-Panel to retrieve odds."
},
},
I am trying to search HazelcastJsonValue, data example for the same.
class A {
B[] listOfB;
}
class B {
int num;
String name;
}
'A' object is present in Hazelcast as HazelcastJsonValue and i want to create query which fetches all objects which contain B for which num = 10 and name = test
hazelcast query for array search using predicate
Predicate.equal("listOfB[any].name","test")
for above scenario query i can make using predicates
Predicate[] arrayOfPredicate = {Predicates.equal("listOfB[any].num",10)
,Predicates.equal("listOfB[any].name","test")};
Predicate p = Predicates.and(arrayOfPredicate);
System.out.println(p.toString()); // (listOfB[any].num=10 AND listOfB[any].name=test)
Example Data in hazelcast
[
{
"listOfB": [
{
"num": 10,
"name": "ab"
},
{
"num": 11,
"name": "test"
}
]
},
{
"listOfB": [
{
"num": 10,
"name": "test"
},
{
"num": 12,
"name": "xyz"
}
]
},
{
"listOfB": [
{
"num": 30,
"name": "abc"
}
]
}
]
Hazelcast query for same
(listOfB[any].num=10 AND listOfB[any].name=test)
But this is not giving desired results instead below result came
[
{
"listOfB": [
{
"num": 10,
"name": "ab"
},
{
"num": 11,
"name": "test"
}
]
},
{
"listOfB": [
{
"num": 10,
"name": "test"
},
{
"num": 12,
"name": "xyz"
}
]
}
]
Desired results are
{
"listOfB": [
{
"num": 10,
"name": "test"
},
{
"num": 12,
"name": "xyz"
}
]
}
How can i get desired results?
Both of the above should've been returned in your result set. Is this not the case? The fact that you're wanting any will return true for the above data. If you limited the filter to listOfB[0], then the 2nd will be returned but I'm sure your intention is to not limit to 1st item only.
I have a two arrays:
Users [
{ "id": 0, "name": "Scott" },
{ "id": 0, "name": "Jan" },
{ "id": 0, "name": "Jack" },
]
Users2Add [
{ "id": 0, "name": "Scott" },
{ "id": 0, "name": "Andy" },
{ "id": 0, "name": "John" },
]
I want to check if new users in Users2Add are already in Users array. If yes don't push(add to array) else add the new User(From User2Add) to Users array. Like:
forEach(var u in Users2Add ) {
if(!(Users.containts(x => x.id == User2Add.idx))) Users.push(u);
}
The problem is that there's no straightforward way to check object equality in JS, and of course:
{a: 1} === {a: 1} //false
A possible solution is to use lodash:
Users2Add.forEach(user => {
if (!Users.some(existingUser = > _.isEqual(existingUser, user))) {
Users.push(user);
}
});
Inside reducer, given a state object:
var state = {
"data": [{
"subset": [{
"id": 1
}, {
"id": 2
}]
}, {
"subset": [{
"id": 10
}, {
"id": 11
}, {
"id": 12
}]
}]
}
As you can see, the data is a nested array, with arrays in each of its elements.
Knowning that action.indexToUpdate will be a index for data, I want to update data[action.indexToUpdate].subset to a new array programmatically. For example, if action.indexToUpdate = 0, then data[0] will be updated from
[{"id":1},{"id":2}]
to
[{"id":4},{"id":5}]
In order to do so, I have:
let newSubset = [{"id":4},{"id":5}]
let newState = update(state.data[action.indexToUpdate], {
subset: {
newSubset,
},
})
But when I executed this, it returns error:
TypeError: value is undefined
on the update founction.
I have been looking at the react ducomentation here: https://facebook.github.io/react/docs/update.html but I couldn't really figure out how to do it. Please advise!
Your update will look like
var obj = {"state" : {
"data": [{
"subset": [{
"id": 1
}, {
"id": 2
}]
}, {
"subset": [{
"id": 10
}, {
"id": 11
}, {
"id": 12
}]
}]
}}
return update(obj, {
"state" : {
"data": {
[action.indexToUpdate]: {
"subset": {
$set: [newSubset]
}
}
}
}
})
In case there are other fields in subset, but you only wish to the change the fields at specific index containing other keys, you would write
return update(obj, {
"state" : {
"data": {
[action.indexToUpdate]: {
"subset": {
[id]: {$merge: newSubset}
}
}
}
}
})