How to get unique/Distinct data from store? - extjs

i am using the extjs. i need to retrieve distinct data from store as per requirement. In my store contains single list not nested list in that have regions like AMERICAS , North Sea and SE Asia. these region it self have subRegion,vesselName and vesselType values. I need to retrive unique value based on region, bacasue it contains many duplicate records. I have tried like as below, but it is not working me. Can anybody tel me how to achieve ?. great appreciated. Thank you.
var vesselStore=Ext.getStore('VesselStatusReportStore');
var arr=new Array();
var obj;
vesselStore.each(function(rec,index)
{
obj=new Object();
if(rec.get('region')=='AMERICAS'){
obj.subRegionAmerica=rec.get('subRegion');
obj.vesselNameAmerica=rec.get('vesselName');
obj.vesselTypeAmerica=rec.get('vesselType');
}
if(rec.get('region')=='NorthSea'){
obj.subRegionNorthSea=rec.get('subRegion');
obj.vesselNameNorthSea=rec.get('vesselName');
obj.vesselTypeNorthSea=rec.get('vesselType');
}
if(rec.get('region')=='SE Asia'){
obj.subRegionSEAsia=rec.get('subRegion');
obj.vesselNameSEAsia=rec.get('vesselName');
obj.vesselTypeSEAsia=rec.get('vesselType');
}
arr.push(obj);
console.log(obj);
});
Json:
[ {
"region" : "AMERICAS",
"startDate" : null,
"subRegion" : "US",
"vesselName" : "Thoma-Sea � Hull #147",
"vesselType" : "PSV"
},
{
"region" : "AMERICAS",
"startDate" : null,
"subRegion" : "US",
"vesselName" : "Thoma-Sea � Hull #148",
"vesselType" : "PSV"
},
{
"region" : "AMERICAS",
"startDate" : null,
"subRegion" : "Mexico",
"vesselName" : "Thoma-Sea � Hull #148",
"vesselType" : "PSV"
}]

It looks like you want to use collect. http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.Store-method-collect
vesselStore.collect('region')

This section doesn't make sense:
obj=new Object();
if(rec.get('region')=='AMERICAS'){
obj.subRegionAmerica=rec.get('subRegion');
obj.vesselNameAmerica=rec.get('vesselName');
obj.vesselTypeAmerica=rec.get('vesselType');
}
if(rec.get('region')=='NorthSea'){
obj.subRegionNorthSea=rec.get('subRegion');
obj.vesselNameNorthSea=rec.get('vesselName');
obj.vesselTypeNorthSea=rec.get('vesselType');
}
if(rec.get('region')=='SE Asia'){
obj.subRegionSEAsia=rec.get('subRegion');
obj.vesselNameSEAsia=rec.get('vesselName');
obj.vesselTypeSEAsia=rec.get('vesselType');
}
arr.push(obj);
You are basically saying "Whatever the region is, copy the record to obj, then add that obj to my array".
I believe you meant something more along these lines:
var vesselStore=Ext.getStore('VesselStatusReportStore');
var iRegions = [];
vesselStore.each(function(rec,index)
{
var iRegionName = rec.get('region');
// Make sure theres a array item with the region name,
// if not create a blank array;
iRegions[ iRegionName ] = iRegions[ iRegionName ] || [];
// Add the record to its corresponding array item.
// (If you don't want the full record, you can just get the
// fields individually like you did in your code).
iRegions[ iRegionName ] = rec;
}
console.log( iRegions );

Related

Why isn't as3 handing my arrays in JSON?

Here I have this json file.
{
"BnUs5hQZkJWLU9jGlpx9Ifq5ocf2" : {
"bio" : "Your bio!\r",
"birthday" : "Date of Birth?",
"location" : "Location?",
"markerBorder" : 1.5542403222038021E7,
"markerColor" : 8222122.31461079,
"name" : "NamesName?",
"profilePrivacy" : 2,
"sex" : "Gender?",
"privacy" : 2,
"points" : {
"-Kc7lfJk3XbPlNyk-wIR" : {
"address" : "dsfsdfasfsfd",
"description" : "status/desription",
"latitude" : 35.2,
"longitude" : -80.7,
"mediaTargets" : "none",
"pub" : false,
"timestamp" : 1486205926658
},
"aaa" : "aaa"
}
}
}
Those random string of charactors are automatically made when I use firebase.
In this scenario, there might be more "points" I will have to take account for. So when I reference points, I should be talking to an array since it contains both "-Kc7lfJk3XbPlNyk-wIR" (an array) and "aaa" (a string).
So why do I get a type error when trying to convert parsedObject.points into an array?
var parsedObject:Object = JSON.parse(e.target.data);
var multiArray:Array = parsedObject.points;
TypeError: Error #1034: Type Coercion failed: cannot convert Object#5c16089 to Array.
I'm basically trying to do the opposite of what this guy is doing.
Edit: I see in the notes that it only handles string, numbers and Boolean values..
I managed to work around it by adding a "parent" node in the object that duplicates the same value as the name of the entire node so I can reference it in the script. Is there a better way to go about this? Seems pretty redundant.
var parsedObject:Object = JSON.parse(e.target.data);
var myPoints:Object = parsedObject["points"];
//Get all trek names
for each (var key:Object in myPoints)
{
trace("Key = " + key.parent);
trace(parsedObject.treks[key.parent].latitude) //Returns -80.7
}
Because Array is a subclass of Object.
var A:Array = new Array();
var B:Object = new Object();
trace(A is Array); // true
trace(A is Object); // true
trace(B is Array); // false
trace(B is Object); // true
B = new Array(); // nothing wrong here
A = new Object(); // throws exception
So, you might want to tell what kind of data you want to obtain in the Array form from the parsedObject.points Object to proceed.
Alternately, that is how you get actual Array from JSON string:
{
"list": [1,2,3,4,5,6]
}
Looks like it's correctly being parsed by JSON.parse to me.
Arrays in JSON use square brackets, braces are interpreted as objects.
You'd only expect an Array from JSON.parse if you had
"points": [
...
]
whereas this is an Object:
"points": {
...
}
I suggest you look into why you aren't getting [] from your source.

node.js loop through object array

I'm trying to store multiple objects from an array as a variable. I really hope that makes sense.
So, I am able to store one element of the array in a variable.
var data = msg.payload.data;
msg.payload = data.observations[0].clientMac;
return msg;
But instead of just the MAC from key 0, I want to loop through each key, grab the mac, and store it in a new array. I'm just not sure how to do that.
Below is a sample of how the data is formatted:
{
"apMac" : "aa:bb:cc:11:22:33",
"apFloors" : [],
"apTags" : [],
"observations" : [{
"ipv4" : null,
"location" : {
"lat" : 5.73212614236217,
"lng" : -5.01730431523174,
"unc" : 1.5059361681363623,
"x" : [],
"y" : []
},
"seenTime" : "2015-09-30T10:59:01Z",
"ssid" : null,
"os" : null,
"clientMac" : "bb:cc:dd:33:22:11",
"seenEpoch" : 1443610741,
"rssi" : 46,
"ipv6" : null,
"manufacturer" : "Hewlett-Packard"
}
]
}
data.observations is just an array of objects. There are many ways to iterate over an array. Here's one:
data.observations.forEach(function(item) {
console.log(item.clientMac);
});
Or, if you want to create an array of them, you can do this:
var macs = data.observations.map(function(item) {
return item.clientMac;
});
console.log(macs); // an array of clientMac properties
You can see documentation for array.map() and array.forEach().
You can also write:
for( var item in data.observations){
console.log(item.bla);
}
or
for(var index=0;index<data.observations.length;index++){
console.log(data.observations[index].bla);
}

Grouping Of Data in AngularJs

I am building a site for a restaurant . On the site I am rendering the restaurant menu on a page .
The Menu Items Json, I am getting from server looks like this : -
{
"_id" : ObjectId("54c3c6e6cd7fe7df22cae87e"),
"restaurant" : ObjectId("54b3a7ef613e89f64654f2b3"),
"name" : "Pasta",
"itemCode" : "PST",
"price" : 240,
"sellingPrice" : 280,
"cuisine" : "Ittalian",
"category" : "starter",
"type" : "non-veg",
"created" : ISODate("2015-01-24T16:23:02.652Z"),
"Head" : pasta
"__v" : 0
}
So basically the requirement is to group menu items on basis of head field (which can be soups, pizza, pastas,etc).
so that all the item with "head" : "soups" will list down together and all item with "head" : "pizza" will list down together .
The way I thought of doing this is through designing custom filter, where I will pass all the unique "head" attribute and I will get data accordingly .
Just need a better and more optimize approach for the situation .
Depending on how often that filter will be called, you should probably just postprocess the data and create a new result set, grouped by the correct value. Something like (untested):
var jsonResults = [{head:'pasta',...},{head:'soups',...}];
, jsonResultsProcessed = { };
, rec
for(var i=0; i<jsonResults.length; i++) {
rec = jsonResults[i];
if(!jsonResultsProcessed[rec.head]) {
jsonResultsProcessed[rec.head] = [ rec ];
} else {
jsonResultsProcessed[rec.head].push(rec);
}
}
$scope.results = jsonResultsProcessed;
and then in your view, you can just refer to results.pizza or whatever.
var dishesPerHead = {};
var heads = [];
angular.forEach(dishes, function(dish) {
var dishesForHead = dishesPerHead[head];
if (!dishesForHead) {
dishesForHead = [];
heads.push(dish.head);
dishesPerHead[dish.head] = dishesForHead;
}
dishesForHead.push(dish);
}
Now you have an array of distinct heads, and for each head, dishesPerHead contains the array of dishes having this head.

how to add a complextype object dynamically to an array

We have created an array of complextype(Carrier field) objects. See below metadata
{ shortName : 'Person',
namespace : 'Demo',
autoGeneratedKeyType : breeze.AutoGeneratedKeyType.Identity,
"dataProperties": [
{
"name": "carriers",
"complexTypeName":"Carrier:#Test",
"isScalar":false
}]
}
The Carrier entity is defined as below:
{
"shortName": "Carrier",
"namespace": "Test",
"isComplexType": true,
"dataProperties": [
{
"name": "Testing",
"isScalar":true,
"dataType": "String"
}
]
}
We have the following matching data for the above entities:
{
carriers: [
{
Testing : 'InputBox1'
},
{
Testing : 'InputBox2'
}
]
}
We are trying to dynamically add the complextype object(Carrier) to the above carriers array by using the following approach:
var test = {
"Testing" : "Test"
};
var result = manager.createEntity('Carrier', test);
The above code throws an exception(undefined is not a function) inside breeze.debug.js at line number 12457(see below code)
entity = entityType.createEntity(initialValues);
The exception is thrown since the complextype entity does not have 'createEntity' function in it.
What are we missing here?
Excellent question - Sorry I didn't have a chance to address this earlier.
When adding a complexType object you need to use the createInstance() method instead of the createEntity.
var thisEntityType = manager.metadataStore.getEntityType('Carrier');
var thisEntity = thisEntityType.createInstance(initialValues);
Basically you get the complexType and then create an instance of it using the values you want assigned. Keep in mind the initial values should be a hash object of course. Often I will include a helper function to do this for me like this -
function createComplexType(entityType, constructorProperties) {
var thisEntityType = manager.metadataStore.getEntityType(entityType);
var thisEntity = thisEntityType.createInstance(constructorProperties);
return thisEntity;
}

Mapreduce split input string into output array

I am dealing with documents like the following one:
> db.productData.find({"upc" : "XXX"}).pretty()
{
"_id" : ObjectId("538dfa3d44e19b2bcf590a77"),
"upc" : "XXX",
"productDescription" : "bla foo bar bla bla fooX barY",
"productSize" : "",
"ingredients" : "foo; bar; foo1; bar1.",
"notes" : "bla bla bla"
}
>
I would like to have a document containing, among the fields, a list/array of splitted ingredients (on the ;). I want to split the string of the original collection into an array of strings.
I would like to map only some of the input fields in the output collection.
I would like to use mapreduce on MongoDB.
I've tried many different ways moving stuff from the map function to the reduce function failing to find a proper solution.
From all the attempts I performed, now I know I need to check for null values etc, so the following one is my last attempt:
The map function:
var mapperProductData = function () {
var ingredientsSplitted = values.ingredientsString.split(';');
var objToEmit = {barcode : "", description : "", ingredients : []};
// checking for null (is this strictly necessary? why?)
if (
this.hasOwnProperty('ingredients')
&& this.hasOwnProperty('productDescription')
&& this.hasOwnProperty('upc')
) {
for (var i = 0; i < ingredientsSplitted.length; i++) {
// I want to emit a new document only when I have all the splitted strings inside the array
if (i == ingredientsSplitted.length - 1) {
objToEmit.barcode = this.upc;
objToEmit.description = this.productDescription;
objToEmit.ingredients = ingredientsSplitted;
emit(this.upc, objToEmit);
}
}
}
};
The reduce function:
var reducerNewMongoCollection = function(key, values) {
return values;
};
The map-reduce call:
db.productData.mapReduce(
mapperProductData,
reducerNewMongoCollection,
{
out : "newMongoCollection" ,
query: { "values" : {$exists: true} }
}
);
I am getting an empty collection in output (newMongoCollection is empty).
What am I doing wrong?
Let's start from the beginning. Your map function should look like this:
var mapperProductData = function () {
var ingredientsSplitted = this.ingredients.split(';');
var objToEmit = {
barcode : this.upc,
description : this.productDescription,
ingredients : ingredientsSplitted
};
emit(this.upc, objToEmit);
};
Your map-reduce call should be:
db.productData.mapReduce(
mapperProductData,
reducerNewMongoCollection,
{
out : "newMongoCollection",
query : {
upc : { $exists : true },
productDescription : { $exists : true },
ingredients : { $exists : true , $type : 4 }
}
}
);
The query part will filter the documents that do have relevant fields. Also the query parameter $type will match only documents where ingredients is an array. This way you don't need to do complicated checking inside your map function and the number of documents sent to map function will be lower.
The result for your test document document will look like this:
key : XXX,
value: {
"barcode" : "XXX",
"description" : "bla foo bar bla bla fooX barY",
"ingredients" : [
"foo",
" bar",
" foo1",
" bar1."
]
}

Resources