rxjs/Angular2 Loop but show different object of a single associative array - arrays

I recently combined two array using rxjs
MyArray = [{
"Field": ["Cars"],
"Type": ["BMW", "Toyota", "Volvo"]
},
{
"Field": ["House"],
"Type": ["Condominium", "TownHouse"],
}
PriceArray = [
{
field: Cars,
distribution: [{"name" : "BMW","price":2},{"name" : "Toyota","price":3}]
},
{
field: People,
distribution: [{"name" : "Condominium","price":3},{"name" : "TownHouse","price":2}]
}]
using rxjs filter
const $MergeData = MyArray.map(val => {
return Object.assign({}, val,this.PriceArray.filter(v => v.Field === val.field)[0])
});
this.mergedArray = $MergeData;
Now it looked this..
mergedArray = [{
"Field": "Cars",
"Type": ["BMW", "Toyota", "Volvo"],
"field" : "Cars",
"distribution" : [
{
"name" : "BMW"
"price": 2 ,
},
{
"name" : "Toyota"
"price": 3 ,
},
{
"name" : "Toyota"
"price": 4 ,
}
]
}, .... (house array here)];
Then I tried to show the item price but its not working
<div *ngFor="let item of mergedArray">
<div *ngFor="let car of item.Field; let i = index">
<p>{{car}} </p>
<p>{{item.distribution.price[i]}} </p>
</div>
</div>
I am hoping for a fix or better if the array should look like this instead
mergedArray = [{
"Field": "Cars",
"Type": ["BMW": 2, "Toyota" : 3, "Volvo" : 4],
}]
Hoping it would me possible as it is much easier to loop.

I think that this is the desired effect, also keep in mind that when using Array.prototype.filter and no elements pass the test the returned value will be [] and if you try to access the [][0] element, the value will be undefined, after that if you try to access some property from that undefined value, it will throw an error.
For example if you try to access the price of Volvo it will throw an error Cannot read property 'price' of undefined, because Volvo doesn't exist in the PriceArray
let priceArray = [
{
"name" : "BMW",
"price": 2
},
{
"name" : "Toyota",
"price": 3
},
{
"name" : "Toyota",
"price": 4
}
];
let myArray = [{
"Field": "Cars",
"Type": ["BMW", "Toyota", "Volvo"]}]
let findPrice= (priceArray,mark)=> priceArray
.find(x=> x.name === mark)
? priceArray.find(x=> x.name === mark).price
: 'No data'
let mergedArray = myArray[0].Type.map(x=> ({[x]:findPrice(priceArray,x)}))
console.log(mergedArray)

Related

React Native - Sort array based off words

Hey guys i have the following array:
Array [
Object {
"data": "Cat Man",
"id": "1",
},
Object {
"data": "Bat Girl",
"id": "2",
},
Object {
"data": "Mr Penguin",
"id": "3",
},
Object {
"data": "Cheeky Cheetah",
"id": "4",
},
]
I am going to take the users input in the form of a search bar, how can i sort the array based off the users input.
So lets say the user inputs
Bat g
the array would be sorted to:
Array [
Object {
"data": "Bat Girl",
"id": "2",
},
Object {
"data": "Cat Man",
"id": "1",
},
Object {
"data": "Mr Penguin",
"id": "3",
},
Object {
"data": "Cheeky Cheetah",
"id": "4",
},
]
How can I achieve this?
I have been searching around the array sort function:
Array.prototype.sort()
However I have only seen how to sort based off number comparisons I have never seen an array sorted based off string values like a search. Please could someone help me with this!
Here is function to search data using string text.
const searchItem = txt => {
let text = txt.toLowerCase();
let tracks = dataArray;
let filterTracks = tracks.filter(item => {
if (item.data.toLowerCase().match(text)) {
return item;
}
});
console.log('filterTracks', filterTracks);
};
Array Should be like this
var dataArray = [
{
data: 'Cat Man',
id: '1',
},
{
data: 'Bat Girl',
id: '2',
},
{
data: 'Mr Penguin',
id: '3',
},
{
data: 'Cheeky Cheetah',
id: '4',
},
];

How to update an embedded document into a nested array?

I have this kind of structure into a Mongo collection :
{
"_id": "12345678",
"Invoices": [
{
"_id": "123456789",
"Currency": "EUR",
"DueTotalAmountInvoice": 768.3699999999999,
"InvoiceDate": "2016-01-01 00:00:00.000",
"Items": [
{
"Item": 10,
"ProductCode": "ABC567",
"Quantity": 1
},
{
"Item": 20,
"ProductCode": "CDE987",
"Quantity": 1
}
]
},
{
"_id": "87654321",
"Currency": "EUR",
"DueTotalAmountInvoice": 768.3699999999999,
"InvoiceDate": "2016-01-01 00:00:00.000",
"Items": [
{
"Item": 30,
"ProductCode": "PLO987",
"Quantity": 1,
"Units": "KM3"
},
{
"Item": 40,
"ProductCode": "PLS567",
"Quantity": 1,
"DueTotalAmountInvoice": 768.3699999999999
}
]
}
]
}
So I have a first object storing several Invoices and each Invoice is storing several Items. An item is an embedded document.
So in relational modelisation :
A customer has 1 or several Invoice
An Invoice has 1 or several Item
I am facing an issue since I am trying to update a specific Item into a specific a specific Invoice. For example I want to change the quantity of the item 10 in Invoice 123456789.
How is it possible to do that in Mongodb ?
I tried :
Push statement but it doesn't seem to work for nested arrays
arrayFilters but it doesn't seem to work for embedded document in nested arrays (only simple value arrays).
Can you give me some advice about it ?
Thank you !
As per your problem description here:
For example I want to change the quantity of the item 10 in Invoice 123456789. I just changed the Quantity to 3. You can perform any operations here as you want. You just need to take note of how I used arrayFilters here.
Try this query:
db.collection.update(
{"_id" : "12345678"},
{$set:{"Invoices.$[element1].Items.$[element2].Quantity":3}},
{multi:true, arrayFilters:[ {"element1._id": "123456789"},{
"element2.Item": { $eq: 10 }} ]}
)
The above query successfully executed from mongo shell (Mongo 3.6.3). And I see this result:
/* 1 */
{
"_id" : "12345678",
"Invoices" : [
{
"_id" : "123456789",
"Currency" : "EUR",
"DueTotalAmountInvoice" : 768.37,
"InvoiceDate" : "2016-01-01 00:00:00.000",
"Items" : [
{
"Item" : 10,
"ProductCode" : "ABC567",
"Quantity" : 3.0
},
{
"Item" : 20,
"ProductCode" : "CDE987",
"Quantity" : 1
}
]
},
{
"_id" : "87654321",
"Currency" : "EUR",
"DueTotalAmountInvoice" : 768.37,
"InvoiceDate" : "2016-01-01 00:00:00.000",
"Items" : [
{
"Item" : 30,
"ProductCode" : "PLO987",
"Quantity" : 1,
"Units" : "KM3"
},
{
"Item" : 40,
"ProductCode" : "PLS567",
"Quantity" : 1,
"DueTotalAmountInvoice" : 768.37
}
]
}
]
}
Is that what you wanted?
Mongo Db has a way to get the specific array element by using its index. For example, you have an array and you need to get [your] index, then in mongo we use dot . but not braces [ ] !! And one thing is important either! - If you are getting the embedded value (in object or array) you must use " " for your way so if you are changing your value inside this must be like that:
yourModel.findOneAndUpdate(
{ _id: "12345678" },
{
$set: {
"Invoices.0.Items.0.Quantity": 10,
},
}
);
0 - is your element indexes in the array!
$set is the operator to set new value
10 - new value
Else you can go further, you can construct your way to the value with the variable indexes. Use string template
yourModel.findOneAndUpdate(
{ _id: "12345678" },
{
$set: {
[`Invoices.${invoiceIndex}.Items.${itemIndex}.Quantity`]:newValue ,
},
}
);
it is the same but you can paste variable indexes

Angularjs - Set default option in select with dynamic ng-model

I have this problem: i created a selects inside a ng-repeat, the ng-model of each select is dinamically generated.
I need to set a default value to these selects, but i don't know how i can do this
HTML
<div ng-controller="ricercaAttivita">
<div class="accordion-group" ng-repeat="masterAttribute in masterAttributes">
<select class="trip dark" ng-change = "search(1, true, true)" ng-model="masterAttribute.Id" ng-options="attr.Id as attr.Value for attr in masterAttribute.Values">
<option value="">Tutte</option>
</select>
</div>
</div>
APP.JS
var tantoSvagoApp = angular.module('tantoSvagoApp');
tantoSvagoApp.controller("ricercaAttivita", function ($scope) {
$scope.masterAttributes = {"id" : "11", nome" : "MARCHE", "values" :
[{ "id": "114", "nome": "ANCONA" }, { "id": "116", "nome": "ASCOLI PICENO" }]
},
{"id" : "12", nome" : "LOMBARDIA", "values" :
[{ "id": "120", "nome": "MILANO" }, { "id": "121", "nome": "BERGAMO" }]
};
});
The ng-model of my select is "masterAttribute.Id", i need to loop every generated select and, in certain conditions, set a particular default option selected.
Something like
$scope.masterAttribute.Id = value;
How i can do this?
Anyone can hel me PLEASE?
just set the selected value object to $scope.masterAttribute. In your controller add
$scope.masterAttribute = masterAttribute.Values[0];
hope this will help.
$scope.masterAttributes should be an array [],
$scope.masterAttributes=[{
"id": "11",
nome " : "
MARCHE ", "
values " : [{
"id": "114",
"nome": "ANCONA"
}, {
"id": "116",
"nome": "ASCOLI PICENO"
}]
},
{
"id": "12",
nome " : "
LOMBARDIA ", "
values " : [{
"id": "120",
"nome": "MILANO"
}, {
"id": "121",
"nome": "BERGAMO"
}]
And finally set default value in select is,
$scope.masterAttribute = $scope.masterAttributes[0].values[0];

How can I check for duplicate nested arrays inside of documents in Mongoose?

Here is an example of a nested document that I have in my collection:
{
"title" : "front-end developer",
"age" : 25,
"name" : "John",
"city" : "London",
"skills" : [
{
"name" : "js",
"project" : "1",
"scores" : [
{
max: 76,
date: date
},
{
max: 56,
date: date
}
]
},
{
"name" : "CSS",
"project" : "5",
"scores" : [
{
max: 86,
date: date
},
{
max: 36,
date: date
},
{
max: 56,
date: date
},
]
}
]
}
Is there a simple way of determining whether other documents have an identical/duplicate structure to the skills array only? e.g. has the same keys, value and array indexes? Any help would be greatly appreciated. Thanks!
Here's how you get that:
collection.aggregate({
"$group": {
"_id": "$skills",
"docs": {
"$push": "$$ROOT"
},
"count": {
$sum: 1
}
}
}, {
$match: {
"count": {
$gt: 1
}
}
})
If you are looking for developers with the same skillset, you can use the $all operator:
var john = db.developers.findOne(...);
var devs = db.developers.find({ 'skills.name': { $all: john.skills.map(x => x.name) } });

Angular pre-select multiple values in Multi Select field

Trying to pre-select multiple values in my selectfield.
My HTML
<select multiple
data-ng-options="e.id for e in myElements"
data-ng-model="mySelect">
</select>
Put data in the select box (works fine)
var elements = [
{ "id": "AAA" },
{ "id": "BBB" },
{ "id": "CCC" },
{ "id": "DDD" },
{ "id": "EEE" },
{ "id": "FFF" },
{ "id": "GGG" }
]
$scope.myElements = elements;
This does NOT work
var preselected = [
{ "id": "BBB" },
{ "id": "DDD" },
{ "id": "FFF" }
]
$scope.mySelect = preselected;
This does NOT work
var preselected = [ "BBB", "DDD", "FFF" ]
$scope.mySelect = preselected;
Anyone got any ideas?
You have two options:
1- Use as and track by if you want objects as selected values (PLUNKER)
ng-options="e as e.id for e in vm.elements track by e.id"
HTML
<select multiple
ng-options="e as e.id for e in vm.elements track by e.id"
ng-model="vm.selecetedValues">
</select>
CONTROLLER
function MainCtrl() {
var vm = this;
vm.elements = [{ "id": "AAA" },{ "id": "BBB" },{ "id": "CCC" }];
vm.selectedValues = [
{ "id": "AAA" },
{ "id": "CCC" }
];
}
2- Only Use as syntax if you want strings or numbers as selected values (PLUNKER)
ng-options="e.id as e.name for e in elements"
first argument e.id is the value of selected option
second argument e.name is the displayed value
In your case: ng-options="e.id as e.id for e in elements"
HTML
<select multiple
ng-options="e.id as e.id for e in vm.elements"
ng-model="vm.selecetedValues">
</select>
CONTROLLER
function MainCtrl() {
var vm = this;
vm.elements = [{ "id": "AAA" },{ "id": "BBB" },{ "id": "CCC" }];
vm.selectedValues= [
"BBB",
"DDD"
];
}

Resources