How to remove object from axios proxy array - axios

The below is slightly simplified...
The Axios request returns data like this:
Proxy {0: {…}, 1: {…}, 2: {…}}
[[Handler]]: Object
[[Target]]: Array(3)
0: {code: "AAA", id: "001", label: "Foo"}
1: {code: "BBB", id: "002", label: "Bar"}
2: {code: "CCC", id: "003", label: "Baz"}
I am trying to remove any objects from this which match items in my array:
var reqData = this.requestData;
var myArr = ["Foo", "Bar"];
for (let index = 0; index < myArr.length; ++index) {
reqData = reqData.filter(function( obj ) {
return obj.label !== myArr[index];
});
}
This works, to a degree. It produces the following:
(1) [Proxy]
0: Proxy {code: "CCC" id: "003", label: "Baz"}
However this data does not output in the vue HTML. I notice the structure has changed and no longer shows Handler and Target.

Push the reqData items to an array
var testarr = [];
for (let index = 0; index < reqData.length; ++index) {
testarr.push({label: reqData[index].label, id: reqData[index].id, code: reqData[index].code });
}
rebuild proxy object
var proxy = new Proxy( testarr, {} );

Related

Issue with mongosh (mongo shell) and $unwind

We've used the following code (saved as example.js) in the past prior to mongosh.
// DB Connection
conn = new Mongo("localhost:27017");
db = conn.getDB("College2");
collSect = db.getCollection("Section");
collStudent = db.getCollection("Student");
// Create IDs
var secID1 = new ObjectId();
var secID2 = new ObjectId();
var stID1 = new ObjectId();
var stID2 = new ObjectId();
var stID3 = new ObjectId();
// Create Students
collStudent.insertOne({
_id: stID1,
uid: 123456789,
firstName: "Ivona",
lastName: "Bok",
year: 3
});
collStudent.insertOne({
_id: stID2,
uid: 234567890,
firstName: "Ivan",
lastName: "Smith",
year: 4
});
collStudent.insertOne({
_id: stID3,
uid: 345678901,
firstName: "Sally",
lastName: "Struthers",
year: 4
});
// insert sections with student references
collSect.insert({
sectionID: "ISTE12301",
title: "My Database Course",
creditHours: 3,
room: "GOL-2650",
studentRefs: [
{
$ref: "Student", $id: stID1, $db: "College2"
},
{
$ref: "Student", $id: stID2, $db: "College2"
}
]
});
collSect.insert({
sectionID: "ISTE23401",
title: "My Other Database Course",
creditHours: 4,
room: "GOL-2620",
studentRefs: [
{
$ref: "Student", $id: stID2, $db: "College2"
},
{
$ref: "Student", $id: stID3, $db: "College2"
}
]
});
// List Sections
print("\nQ2\n");
print("List Sections\n");
result = collSect.find();
while (result.hasNext()) {
printjson(result.next());
}
// List Students
print("List Students\n");
result = collStudent.find();
while (result.hasNext()) {
printjson(result.next());
}
// Use unwind and list results
print("List Sections with unwind\n");
result = collSect.find();
while (result.hasNext()) {
printjson(result.next());
}
result = collSect.aggregate([{$unwind: "$studentRefs"}]);
// Print the section/student combination
while (result.hasNext()) {
doc = result.next();
studRef = doc.studentRefs;
doc2 = db[studRef.$ref].findOne({_id: studRef.$id});
print(doc.sectionID, doc2.firstName, doc2.lastName);
}
If I go into mongosh and issue load("example.js"), after unwinding when trying to build doc2 it gets null:
TypeError: Cannot read property 'firstName' of null
However, if I am at the command prompt and issue mongo example.js, it works fine.
This seems odd since MongoDB is pushing users to mongosh. Does anyone know why this doesn't work in mongosh?

Store array of string into the mongoDB collection

I am very new to MongoDB and mongoose I have a model name called agent
agent.model.js
const mongoose = require('mongoose')
const agentSchema = new mongoose.Schema({
agent: {
type: String,
required: true
}
})
const Agent = mongoose.model('Agent', agentSchema)
module.exports = Agent;
Now I have a array of string:
const agentName = ['john', 'alex', 'david'];
Now I want to store this array into the mongoDB as an individual agent.
like this:
[
{
"_id": "6000977d9b94f52960955066",
"agent": "john",
"__v": 0
},
{
"_id": "6000977d9b94f52960955067",
"agent": "alex",
"__v": 0
},
{
"_id": "6000977d9b94f52960955068",
"agent": "david",
"__v": 0
}
]
Note: Right now First I am converting my array of string into the array of object using loop like this:
agentName = agentName.map((e) => {return {agent: e}})
//output of above line of code
[ { agent: 'Alex Watson' },
{ agent: 'John Snow' },
{ agent: 'Rita Ora' } ]
Then I am saving the agentName.
But I am looking for some better approach, Like in which there is no need of converting the array of string into the array of object.
you must to use insertMany() function is used to insert multiple documents into a collection. It accepts an array of documents to insert into the collection. like following code, so have to create a array of abjects, that you created
note: in your question define const agentName next step assign result of map to the constant variable, so this is wrong
const agentName = ['john', 'alex', 'david'];
let arr = agentName.map((e) => {return {agent: e}})
Agent.insertMany(arr).then(function(){
console.log("Data inserted") // Success
}).catch(function(error){
console.log(error) // Failure
});

Dispatch total of Vue child computed values to parent

I cannot figure out how to use the $dispatch method to send data from a Vue child to a Vue parent. I have a component with multiple instances as follows:
Vue.component('receipt', {
template: '#receipt-template',
data: function() {
return {
tip: ''
};
},
methods: {
addSale: function() {
this.sales.push(
{amount: 1, desc: '', price: 0.00}
);
},
removeSale: function(index) {
this.sales.splice(index, 1)
}
},
computed: {
subtotal: function() {
var result = 0;
this.sales.forEach(function (sale) {
return result += +sale.price;
});
var subtotal = Math.round(100 * result) / 100;
return subtotal.toFixed(2);
},
tax: function() {
var tax = this.subtotal * .08;
return tax.toFixed(2);
},
total: function() {
var total = Number(this.subtotal) + Number(this.tax) + Number(this.tip);
return total.toFixed(2);
this.$dispatch(this.total);
}
},
props: [ 'header', 'date', 'sales' ]
})
And my Vue instance looks like:
var vm = new Vue({
el: '#content',
data: {
sales1: [
{amount: 1, desc: "Dante's Inferno", price: 13.99},
{amount: 1, desc: "Espresso", price: 5.25},
{amount: 1, desc: "The Sun Also Rises", price: 11.99},
{amount: 1, desc: "Spanish Coffee", price: 1.99}
],
sales2: [
{amount: 1, desc: "Huckleberry Finn", price: 14.95},
{amount: 1, desc: "Americano", price: 2.29},
{amount: 1, desc: "Pride & Prejudice", price: 12.95},
{amount: 1, desc: "Black Tea Latte", price: 4.25},
{amount: 1, desc: "Scone", price: 3.25}
],
company: 'Between The Covers & Grinders Cafe'
},
computed: {
grand: function() {
}
}
})
I have multiple instances of the 'Receipt' component and therefore multiple values being computed from the component's computed 'total' function. How can I dispatch the values of the component's instances 'total' functions and get my 'grandtotal' in the parent instance
You have to create a method in your component that 'dispatches' an event, like this:
methods: {
yourMethodName: function(){
this.$dispatch('eventName', data);
}
}
eventName is the name of the event that your app will be expecting and will pick when it's dispatched, the data is just the data that will be available for use when the event is picked.
In your app instance you can just define a prop called 'events' pick the event and do something with it. Like this:
events: {
'eventName': function(data){
//do something with it
}
}
Like this, everytime 'yourMethod' (your component's method) is called it will dispatch the event named 'eventName' and your app will pick and handle it.
Hope that helps!

How to iterate over multiple arrays without nested observables

I must iterate over array, find correspondent objects in other array an merge the result in a object.
Assume I have three arrays
var users = [
{ name: "A", type: 2, level: 1 },
{ name: "B", type: 1, level: 2 }
]
var types = [
{ description: "Type 1", id: 1 },
{ description: "Type 2", id: 2 }
]
var levels = [
{ description: "Level 1", id: 1 },
{ description: "Level 2", id: 1 }
]
I want to have following result:
var users = [
{ name: "A", type: 2, level: 1, levelDescription: "Level 1", typeDescription: "Type 2" },
{ name: "B", type: 1, level: 2, levelDescription: "Level 2", typeDescription: "Type 1" }
]
I know I can achieve it like that
var usersObservable = RX.Observable.fromArray(users);
var typesObservable = Rx.Observable.fromArray(types);
var levelsOBservable = Rx.Observable.fromArray(levels);
var uiUsers= [];// not really needed because I will use the same users array again.
usersObservable.map(function(user) {
typesObservable.filter(function(type) {
return type.id == user.type;
}).subscribeOnNext(function(userType) {
user.typeDescription = userType.description;
});
return user;
}).map(function(user) {
levelsOBservable.filter(function(level) {
return level.id == user.levelId;
}).subscribeOnNext(function(level) {
user.levelDescription = level.description;
});
return user;
})
.subscribeOnNext(function(user) {
uiUsers.push(user);
})
I would like to have a solution without nested Observables.
Thanks.
I am not sure why you are using Rx at all for this problem. You have data in space (i.e. arrays), not data over time (i.e. an observable sequence). But you force these arrays into Rx to then create a very complicated solution.
I think you are looking for something like the answer here https://stackoverflow.com/a/17500836/393615 where you would join the source array types. In your case you just "inner-join" twice to combine all three data sets.
You can archive this by using the switchMap operator that combines the result of a filtered stream with the latest value of the original stream and uses a projection function to merge the results into a single object. This can be generalised in your example such that you can use a generic higher order function in both cases. See fiddle.
Full code (ES2015, RxJS5):
const users = [
{ name: "A", type: 2, level: 1 },
{ name: "B", type: 1, level: 2 }
];
const types = [
{ description: "Type 1", id: 1 },
{ description: "Type 2", id: 2 }
];
const levels = [
{ description: "Level 1", id: 1 },
{ description: "Level 2", id: 2 }
];
const users$ = Rx.Observable.from(users);
const types$ = Rx.Observable.from(types);
const levels$ = Rx.Observable.from(levels);
function join(s$, sourceProperty, targetProperty, streamProperty) {
return function(initObj) {
const stream$ = s$.filter(x => x.id === initObj[sourceProperty]);
return Rx.Observable.combineLatest(
Rx.Observable.of(initObj),
stream$,
(obj, streamObj) => {
const prop = streamObj[streamProperty];
return Object.assign({}, obj, { [targetProperty]: prop });
}
);
};
}
users$
.switchMap(join(types$, 'type', 'typeDescription', 'description'))
.switchMap(join(levels$, 'level', 'levelDescription', 'description'))
.subscribe(x => console.log(x));

In an array of objects, how can I aggregate based on object property?

Say I have the following array of objects:
dataArray = [
{ id: "a", score: 1 },
{ id: "b", score: 2 },
{ id: "c", score: 5 },
...
{ id: "a", score: 3 },
...
{ id: "c", score: 2},
...
]
How can I obtain a resultArray like the following:
resultArray = [
{ id: "a", score: sum of all the scores when id is a },
{ id: "b", score: sum of all the scores when id is b },
...
...
]
If you use the underscore library:
_.map _.groupBy(dataArray, 'id'), (v, k) ->
{id: k, score: _.reduce(v, ((m, i) -> m + i['score']), 0) }
The Underscore version is probably the most succinct. This is a plain CoffeeScript version that only creates one auxiliary object to have fast access by id and make the whole thing O(n):
aggregateScores = (dataArr) ->
scores = {}
for {id, score} in dataArr
scores[id] = (scores[id] or 0) + score
{id, score} for id, score of scores
console.log aggregateScores [
{ id: "a", score: 1 }
{ id: "b", score: 2 }
{ id: "c", score: 5 }
{ id: "a", score: 3 }
{ id: "c", score: 2 }
]
# Output:
# [{id:"a", score:4}, {id:"b", score:2}, {id:"c", score:7}]
This is just plain JavaScript, but here is the long answer to your question:
function aggregate(values, init, keyGetter, valueGetter, aggregator) {
var results = {}
for (var index = 0; index != values.length; ++index) {
var value = values[index]
var key = keyGetter(value)
var soFar;
if (key in results) {
soFar = results[key]
} else {
soFar = init
}
value = valueGetter(value)
results[key] = aggregator(soFar, value)
}
return results
}
var array = [
{ id: 'a', score: 1 },
{ id: 'b', score: 2 },
{ id: 'c', score: 5 },
{ id: 'a', score: 3 },
{ id: 'c', score: 2 }
]
function keyGetter(value) {
return value.id
}
function valueGetter(value) {
return value.score
}
function aggregator(sum, value) {
return sum + value
}
function ready() {
var results = aggregate(array, 0, keyGetter, valueGetter, aggregator)
console.info(results)
}
Here's a straightforward coffeescript version:
data = [
{ id: "a", score: 1 }
{ id: "b", score: 2 }
{ id: "a", score: 5 }
{ id: "c", score: 2 }
{ id: "b", score: 3 }
]
# Aggregate scores in a map.
resultSet = {}
for obj in data
resultSet[obj.id] ?= 0
resultSet[obj.id] += obj.score
console.log resultSet
# Create array from map.
resultArr = for key, val of resultSet
{ id: key, score: val}
console.log resultArr
The output is:
{ a: 6, b: 5, c: 2 }
[ { id: 'a', score: 6 },
{ id: 'b', score: 5 },
{ id: 'c', score: 2 } ]
I'm sure it's possible to create a fancier solution using the functions in underscore, but the coffeescript solution isn't bad so I went for something simple to understand.
It's a bit overkill if this is the only aggregation you want to do but there is a nicely documented aggregation library called Lumenize, that does simple group-by operations like this in addition to more advanced pivot table, n-dimensional cubes, hierarchical roll-ups, and timezone-precise time-series aggregations.
Here is the jsFiddle for a Lumenize solution.
If you want to try it in node.js:
npm install Lumenize --save
then put this into a file named lumenizeGroupBy.coffee:
lumenize = require('Lumenize')
dataArray = [
{ id: "a", score: 1 },
{ id: "b", score: 2 },
{ id: "c", score: 5 },
{ id: "a", score: 3 },
{ id: "c", score: 2}
]
dimensions = [{field:'id'}]
metrics = [{field: 'score', f: 'sum', as: 'sum'}]
config = {dimensions, metrics}
cube = new lumenize.OLAPCube(config, dataArray)
console.log(cube.toString(null, null, 'sum'))
and run
coffee lumenizeGroupBy.coffee