Count of boolean values of an array in angular2 - angular2-routing

this.employee = [
{
name: "A",
isexperienced: true;
},
{
name: "B",
isexperienced: true;
},
{
name: "C",
isexperienced: false;
},
//here i need the count of true values

Try:
const experienced = this.employee.reduce((acc, e) => e.isexperienced ? acc+1 : acc, 0);
Secondly, your employee array is not correct:
There should be no ; after true, false
There is no closing ]

Related

FOS Elastic range price with discount

I want to get all the products by range price with discount.
this is what it looks like in sql:
WHERE (
CASE WHEN p.discount IS NOT NULL THEN ROUND(
p.unit_price * (100 - p.discount) / 100, 1)
ELSE p0_.unit_price END ) >= :min
AND (
CASE WHEN p.discount IS NOT NULL THEN ROUND(
p.unit_price * (100 - p.discount) / 100, 1)
ELSE p0_.unit_price END ) <= :max
is there a way to do the same with range condition?
$fieldRange = new \Elastica\Query\Range('unitPrice', array('gte' => 300, 'lte' => 1500));
here is my config:
fos_elastica:
clients:
default: { url: '%env(ELASTICSEARCH_URL)%' }
indexes:
product:
properties:
unitPrice:
type: integer
discount:
type: keyword
attributeValues:
type: "nested"
properties:
value:
type: keyword
product:
type: keyword
persistence:
driver: orm
model: App\Entity\Product
provider: ~
listener: ~
finder: ~
here is the full query:
$query = new \Elastica\Query();
$query->setSize(0);
$boolQuery = new \Elastica\Query\BoolQuery();
/* filter checked */
$fieldQuery = new \Elastica\Query\Match();
$fieldQuery->setFieldQuery('attributeValues.value', 'Brand');
$domainQuery = new \Elastica\Query\Nested();
$domainQuery->setPath('attributeValues');
$domainQuery->setQuery($fieldQuery);
$fieldQuery2 = new \Elastica\Query\Match();
$fieldQuery2->setFieldQuery('attributeValues.value', 'Another Brand');
$domainQuery2 = new \Elastica\Query\Nested();
$domainQuery2->setPath('attributeValues');
$domainQuery2->setQuery($fieldQuery2);
$fieldRange = new \Elastica\Query\Range('unitPrice', array('gte' => 300, 'lte' => 1500));
$boolQuery->addMust($domainQuery);
$boolQuery->addMust($domainQuery2);
$boolQuery->addMust($fieldRange);
$query->setQuery($boolQuery);
$agg = new \Elastica\Aggregation\Nested('attributeValues', 'attributeValues');
$names = new \Elastica\Aggregation\Terms('value');
$cardinality = new \Elastica\Aggregation\Cardinality('unique_products');
$cardinality->setField('attributeValues.product');
$names->setField('attributeValues.value');
$names->setSize(100);
$names->addAggregation($cardinality);
$agg->addAggregation($names);
$query->addAggregation($agg);
$companies = $this->finder->findPaginated($query);
$asd = $companies->getAdapter()->getAggregations();
here is the result:
array(
"attributeValues" => array:2(
"doc_count" => 406,
"value" => array:3(
"doc_count_error_upper_bound" => 0,
"sum_other_doc_count" => 0,
"buckets" => array:42(
2 => array:3(
"key" => "Another Brand",
"doc_count" => 15,
"unique_products" => array:1(
"value" => 9
)
)
)
)
)
);
here is native request (just in case):
{
"size": 0,
"query": {
"bool": {
"must": [
{
"nested": {
"path": "attributeValues",
"query": {
"match": {
"attributeValues.value": {
"query": "Brand"
}
}
}
}
},
{
"nested": {
"path": "attributeValues",
"query": {
"match": {
"attributeValues.value": {
"query": "Another Brand"
}
}
}
}
},
{
"range": {
"unitPrice": {
"gte": 300,
"lte": 1500
}
}
}
]
}
},
"aggs": {
"attributeValues": {
"nested": {
"path": "attributeValues"
},
"aggs": {
"value": {
"terms": {
"field": "attributeValues.value",
"size": 100
},
"aggs": {
"unique_products": {
"cardinality": {
"field": "attributeValues.product"
}
}
}
}
}
}
}
}
a little explanation - I am making a smart filter that disables options when there are no products in it, which I calculate with this query. But I don't know how to calculate the price range with a discount (%) in elastica. I show how I do it in sql.

Find path to object in object nested array

I have an object, of which parameters contain and array of object. I receive 1 object id and I need to find its position in that whole mess. With procedural programming I got it working with:
const opportunitiesById = {
1: [
{ id: 1, name: 'offer 1' },
{ id: 2, name: 'offer 1' }
],
2: [
{ id: 3, name: 'offer 1' },
{ id: 4, name: 'offer 1' }
],
3: [
{ id: 5, name: 'offer 1' },
{ id: 6, name: 'offer 1' }
]
};
const findObjectIdByOfferId = (offerId) => {
let opportunityId;
let offerPosition;
const opportunities = Object.keys(opportunitiesById);
opportunities.forEach(opportunity => {
const offers = opportunitiesById[opportunity];
offers.forEach((offer, index) => {
if (offer.id === offerId) {
opportunityId = Number(opportunity);
offerPosition = index;
}
})
});
return { offerPosition, opportunityId };
}
console.log(findObjectIdByOfferId(6)); // returns { offerPosition: 1, opportunityId: 3 }
However this is not pretty and I want to do that in a functional way.
I've looked into Ramda, and I can find an offer when I'm looking into a single array of offers, but I can't find a way to look through the entire object => each array to find the path to my offer.
R.findIndex(R.propEq('id', offerId))(opportunitiesById[1]);
The reason I need to know the path is because I then need tho modify that offer with new data and update it back where it is.
Thanks for any help
You could piece it together using lots of little functions but I want to show you how to encode your intentions in a more straightforward way. This program has an added benefit that it will return immediately. Ie, it will not continue to search thru additional key/value pairs after a match is found.
Here's a way you can do it using mutual recursion. First we write findPath -
const identity = x =>
x
const findPath =
( f = identity
, o = {}
, path = []
) =>
Object (o) === o
? f (o) === true
? path
: findPath1 (f, Object .entries (o), path)
: undefined
If the input is an object, we pass it to the user's search function f. If the user's search function returns true, a match has been found and we return the path. If there is not match, we search each key/value pair of the object using a helper function. Otherwise, if the input is not an object, there is no match and nothing left to search, so return undefined. We write the helper, findPath1 -
const None =
Symbol ()
const findPath1 =
( f = identity
, [ [ k, v ] = [ None, None ], ...more ]
, path = []
) =>
k === None
? undefined
: findPath (f, v, [ ...path, k ])
|| findPath1 (f, more, path)
If the key/value pairs have been exhausted, there is nothing left to search so return undefined. Otherwise we have a key k and a value v; append k to the path and recursively search v for a match. If there is not a match, recursively search the remaining key/values, more, using the same path.
Note the simplicity of each function. There's nothing happening except for the absolute minimum number of steps to assemble a path to the matched object. You can use it like this -
const opportunitiesById =
{ 1:
[ { id: 1, name: 'offer 1' }
, { id: 2, name: 'offer 1' }
]
, 2:
[ { id: 3, name: 'offer 1' }
, { id: 4, name: 'offer 1' }
]
, 3:
[ { id: 5, name: 'offer 1' }
, { id: 6, name: 'offer 1' }
]
}
findPath (offer => offer.id === 6, opportunitiesById)
// [ '3', '1' ]
The path returned leads us to the object we wanted to find -
opportunitiesById['3']['1']
// { id: 6, name: 'offer 1' }
We can specialize findPath to make an intuitive findByOfferId function -
const findByOfferId = (q = 0, data = {}) =>
findPath (o => o.id === q, data)
findByOfferId (3, opportunitiesById)
// [ '2', '0' ]
opportunitiesById['2']['0']
// { id: 3, name: 'offer 1' }
Like Array.prototype.find, it returns undefined if a match is never found -
findByOfferId (99, opportunitiesById)
// undefined
Expand the snippet below to verify the results in your own browser -
const identity = x =>
x
const None =
Symbol ()
const findPath1 =
( f = identity
, [ [ k, v ] = [ None, None ], ...more ]
, path = []
) =>
k === None
? undefined
: findPath (f, v, [ ...path, k ])
|| findPath1 (f, more, path)
const findPath =
( f = identity
, o = {}
, path = []
) =>
Object (o) === o
? f (o) === true
? path
: findPath1 (f, Object .entries (o), path)
: undefined
const findByOfferId = (q = 0, data = {}) =>
findPath (o => o.id === q, data)
const opportunitiesById =
{ 1:
[ { id: 1, name: 'offer 1' }
, { id: 2, name: 'offer 1' }
]
, 2:
[ { id: 3, name: 'offer 1' }
, { id: 4, name: 'offer 1' }
]
, 3:
[ { id: 5, name: 'offer 1' }
, { id: 6, name: 'offer 1' }
]
}
console .log (findByOfferId (3, opportunitiesById))
// [ '2', '0' ]
console .log (opportunitiesById['2']['0'])
// { id: 3, name: 'offer 1' }
console .log (findByOfferId (99, opportunitiesById))
// undefined
In this related Q&A, I demonstrate a recursive search function that returns the matched object, rather than the path to the match. There's other useful tidbits to go along with it so I'll recommend you to give it a look.
Scott's answer inspired me to attempt an implementation using generators. We start with findPathGen -
const identity = x =>
x
const findPathGen = function*
( f = identity
, o = {}
, path = []
)
{ if (Object (o) === o)
if (f (o) === true)
yield path
else
yield* findPathGen1 (f, Object .entries (o), path)
}
And using mutual recursion like we did last time, we call on helper findPathGen1 -
const findPathGen1 = function*
( f = identity
, entries = []
, path = []
)
{ for (const [ k, v ] of entries)
yield* findPathGen (f, v, [ ...path, k ])
}
Finally, we can implement findPath and the specialization findByOfferId -
const first = ([ a ] = []) =>
a
const findPath = (f = identity, o = {}) =>
first (findPathGen (f, o))
const findByOfferId = (q = 0, data = {}) =>
findPath (o => o.id === q, data)
It works the same -
findPath (offer => offer.id === 3, opportunitiesById)
// [ '2', '0' ]
findPath (offer => offer.id === 99, opportunitiesById)
// undefined
findByOfferId (3, opportunitiesById)
// [ '2', '0' ]
findByOfferId (99, opportunitiesById)
// undefined
And as a bonus, we can implement findAllPaths easily using Array.from -
const findAllPaths = (f = identity, o = {}) =>
Array .from (findPathGen (f, o))
findAllPaths (o => o.id === 3 || o.id === 6, opportunitiesById)
// [ [ '2', '0' ], [ '3', '1' ] ]
Verify the results by expanding the snippet below
const identity = x =>
x
const findPathGen = function*
( f = identity
, o = {}
, path = []
)
{ if (Object (o) === o)
if (f (o) === true)
yield path
else
yield* findPathGen1 (f, Object .entries (o), path)
}
const findPathGen1 = function*
( f = identity
, entries = []
, path = []
)
{ for (const [ k, v ] of entries)
yield* findPathGen (f, v, [ ...path, k ])
}
const first = ([ a ] = []) =>
a
const findPath = (f = identity, o = {}) =>
first (findPathGen (f, o))
const findByOfferId = (q = 0, data = {}) =>
findPath (o => o.id === q, data)
const opportunitiesById =
{ 1:
[ { id: 1, name: 'offer 1' }
, { id: 2, name: 'offer 1' }
]
, 2:
[ { id: 3, name: 'offer 1' }
, { id: 4, name: 'offer 1' }
]
, 3:
[ { id: 5, name: 'offer 1' }
, { id: 6, name: 'offer 1' }
]
}
console .log (findByOfferId (3, opportunitiesById))
// [ '2', '0' ]
console .log (findByOfferId (99, opportunitiesById))
// undefined
// --------------------------------------------------
const findAllPaths = (f = identity, o = {}) =>
Array .from (findPathGen (f, o))
console .log (findAllPaths (o => o.id === 3 || o.id === 6, opportunitiesById))
// [ [ '2', '0' ], [ '3', '1' ] ]
I would transform your object into pairs.
So for example transforming this:
{ 1: [{id:10}, {id:20}],
2: [{id:11}, {id:21}] }
into that:
[ [1, [{id:10}, {id:20}]],
[2, [{id:11}, {id:21}]] ]
Then you can iterate over that array and reduce each array of offers to the index of the offer you're looking for. Say you're looking for offer #21, the above array would become:
[ [1, -1],
[2, 1] ]
Then you return the first tuple which second element isn't equal to -1:
[2, 1]
Here's how I'd suggest doing this:
const opportunitiesById = {
1: [ { id: 10, name: 'offer 1' },
{ id: 20, name: 'offer 2' } ],
2: [ { id: 11, name: 'offer 3' },
{ id: 21, name: 'offer 4' } ],
3: [ { id: 12, name: 'offer 5' },
{ id: 22, name: 'offer 6' } ]
};
const findOfferPath = (id, offers) =>
pipe(
toPairs,
transduce(
compose(
map(over(lensIndex(1), findIndex(propEq('id', id)))),
reject(pathEq([1], -1)),
take(1)),
concat,
[]))
(offers);
console.log(findOfferPath(21, opportunitiesById));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {pipe, transduce, compose, map, over, lensIndex, findIndex, propEq, reject, pathEq, take, concat, toPairs} = R;</script>
Then you can take that path to modify your offer as you see fit:
const opportunitiesById = {
1: [ { id: 10, name: 'offer 1' },
{ id: 20, name: 'offer 2' } ],
2: [ { id: 11, name: 'offer 3' },
{ id: 21, name: 'offer 4' } ],
3: [ { id: 12, name: 'offer 5' },
{ id: 22, name: 'offer 6' } ]
};
const updateOffer = (path, update, offers) =>
over(lensPath(path), assoc('name', update), offers);
console.log(updateOffer(["2", 1], '🌯', opportunitiesById));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {over, lensPath, assoc} = R;</script>
Here's another approach:
We start with this generator function:
function * getPaths(o, p = []) {
yield p
if (Object(o) === o)
for (let k of Object .keys (o))
yield * getPaths (o[k], [...p, k])
}
which can be used to find all the paths in an object:
const obj = {a: {x: 1, y: 3}, b: {c: 2, d: {x: 3}, e: {f: {x: 5, g: {x: 3}}}}}
;[...getPaths(obj)]
//~> [[], ["a"], ["a", "x"], ["a", "y"], ["b"], ["b", "c"], ["b", "d"],
// ["b", "d", "x"], ["b", "e"], ["b", "e", "f"], ["b", "e", "f", "x"],
// ["b", "e", "f", "g"], ["b", "e", "f", "g", "x"]]
and then, with this little helper function:
const path = (ps, o) => ps.reduce((o, p) => o[p] || {}, o)
we can write
const findPath = (predicate, o) =>
[...getPaths(o)] .find (p => predicate (path (p, o) ) )
which we can call like
console.log(
findPath (a => a.x == 3, obj)
) //~> ["b","d"]
We can then use these functions to write a simple version of your function:
const findByOfferId = (id, data) =>
findPath (o => o.id === id, data)
const opportunitiesById = {
1: [ { id: 10, name: 'offer 1' }, { id: 20, name: 'offer 2' } ],
2: [ { id: 11, name: 'offer 3' }, { id: 21, name: 'offer 4' } ],
3: [ { id: 12, name: 'offer 5' }, { id: 22, name: 'offer 6' } ]
}
console.log(
findByOfferId (22, opportunitiesById)
) //~> ["3", "1"]
console.log(
findByOfferId (42, opportunitiesById)
) //~> undefined
It is trivial to extend this to get all paths for which the value satisfies the predicate, simply replacing find with filter:
const findAllPaths = (predicate, o) =>
[...getPaths(o)] .filter (p => predicate (path(p, o) ) )
console.log(
findAllPaths (a => a.x == 3, obj)
) //=> [["b","d"],["b","e","f","g"]]
There is a concern with all this, though. Even though findPath only needs to find the first match, and even though getPaths is a generator and hence lazy, we force the full run of it with [...getPaths(o)]. So it might be worth using this uglier, more imperative version:
const findPath = (predicate, o) => {
let it = getPaths(o)
let res = it.next()
while (!res.done) {
if (predicate (path (res.value, o) ) )
return res.value
res = it.next()
}
}
This is what it looks like all together:
function * getPaths(o, p = []) {
yield p
if (Object(o) === o)
for (let k of Object .keys (o))
yield * getPaths (o[k], [...p, k])
}
const path = (ps, o) => ps.reduce ((o, p) => o[p] || {}, o)
// const findPath = (pred, o) =>
// [...getPaths(o)] .find (p => pred (path (p, o) ) )
const findPath = (predicate, o) => {
let it = getPaths(o)
let res = it.next()
while (!res.done) {
if (predicate (path (res.value, o) ) )
return res.value
res = it.next()
}
}
const obj = {a: {x: 1, y: 3}, b: {c: 2, d: {x: 3}, e: {f: {x: 5, g: {x: 3}}}}}
console.log(
findPath (a => a.x == 3, obj)
) //~> ["b","d"]
const findAllPaths = (pred, o) =>
[...getPaths(o)] .filter (p => pred (path(p, o) ) )
console.log(
findAllPaths (a => a.x == 3, obj)
) //~> [["b","d"],["b","e","f","g"]]
const findByOfferId = (id, data) =>
findPath (o => o.id === id, data)
const opportunitiesById = {
1: [ { id: 10, name: 'offer 1' }, { id: 20, name: 'offer 2' } ],
2: [ { id: 11, name: 'offer 3' }, { id: 21, name: 'offer 4' } ],
3: [ { id: 12, name: 'offer 5' }, { id: 22, name: 'offer 6' } ]
}
console.log(
findByOfferId (22, opportunitiesById)
) //~> ["3", "1"]
console.log(
findByOfferId (42, opportunitiesById)
) //~> undefined
Another brief note: the order in which the paths are generated is only one possibility. If you want to change from pre-order to post-order, you can move the yield p line in getPaths from the first line to the last one.
Finally, you asked about doing this with functional techniques, and mentioned Ramda. As the solution from customcommander shows, you can do this with Ramda. And the (excellent as always) answer from user633183 demonstrates, it's possible to do this with mainly functional techniques.
I still find this a somewhat simpler approach. Kudos to customcommander for finding a Ramda version, because Ramda is not particularly well-suited for recursive tasks, but still the obvious approach to something that has to visit the nodes of a recursive structure like a JS object is to use a recursive algorithm. I'm one of the authors of Ramda, and I haven't even tried to understand how that solution works.
Update
user633183 pointed out that this would be simpler, and still lazy:
const findPath = (predicate, o) => {
for (const p of getPaths(o))
if (predicate (path (p, o)) )
return p
}

Groovy recursive deep object compare not reporting failures

The answer to this question can be found in this link provided by #bdkosher:
kousenit.wordpress.com/2014/04/16/the-closure-of-no-return
I am attempting to write a recursive function that compares to complex objects (JSON objects) and reports on the differences of each. The code outputs correctly but the failure is not reported as subsequent comparisons take precedent over an earlier failure.
I'm new to groovy so I'm sure there are groovier ways to write it.
The code:
public boolean diffObjects(Object left, Object right)
{
if (left == null || right == null) {
println "Object comparison failure: One or both object null."
return false
}
if (left.getClass() != right.getClass()) {
println "Object comparison failure: Mismatch object classes."
return false
}
if (isArray(left)) {
if (left.size() != right.size()) {
println "Array comparison failure: Object size mismatch."
println "Left has " + left.size() + " items. Right has " + right.size() + " items."
println "Left Object:"
println left
println "Right Object:"
println right
return false
}
for(int i=0; i < left.size(); i++) {
// May detect matching items here if sort of objects is problem
diffObjects(left[i], right[i])
}
} else if (isLazyMap(left)) {
String[] leftKeys = left.keySet()
String[] rightKeys = right.keySet()
if (leftKeys != rightKeys) {
println "Map comparison failure: Left keys do not match right keys."
println "Left " + leftKeys.toString()
println "Right " + rightKeys.toString()
return false
}
leftKeys.each {
if (isArray(left[it])) {
// May detect matching items here if sort of objects is problem
diffObjects( left[it], right[it])
} else {
if (isValue(left[it])) {
if (left[it].toString() != right[it].toString()) {
println "String comparison failure: Left " + it + " value does not match right value."
println "Left " + left[it]
println "Right " + right[it]
return false
}
}
}
}
}
}
Sample data:
[
{
"productId": "141810",
"sizes": [
{
"sku": "11926",
"size": "L",
"gtin": "008206",
"localizedSize": "L",
"skuCountryItems": [
{
"country": "CN",
"commodityCode": null,
"vat": 17
}
],
"available": false
},
{
"sku": "1192",
"size": "M",
"gtin": "0082065234",
"localizedSize": "M",
"skuCountryItems": [
{
"country": "CN",
"commodityCode": null,
"vat": 17
}
],
"available": false
},
{
"sku": "1192",
"size": "S",
"gtin": "0082065234",
"localizedSize": "S",
"skuCountryItems": [
{
"country": "CN",
"commodityCode": null,
"vat": 17
}
],
"available": false
},
{
"sku": "1192",
"size": "XL",
"gtin": "0082065234",
"localizedSize": "XL",
"skuCountryItems": [
{
"country": "CN",
"commodityCode": null,
"vat": 17
}
],
"available": true
}
]
}
]
Any help would be appreciated. Thanks in advance.
Here's an alternative method:
def a = ['a', 'b', 'c']
def b = ['a', 'z', 'c']
def c = [
[sku: 'abc', size: 'L'],
[sku: '123', size: 'S']
]
def d = [
[sku: 'abc', size: 'L'],
[sku: 'xyz', size: 'S']
]
use(DiffMixin) {
assert a.diff(b) == [
[
[self:'b', other:'z'],
[self:[name:'bytes', value:[98]], other:[name:'bytes', value:[122]]]
]
]
println c.diff(d)
}
class DiffMixin {
static List diff(Object self, Object other) {
def diffs = []
if(self != other) {
diffs << [
'self': self.toString(),
'other': other.toString()
]
}
self.properties.inject(diffs) {list, entry ->
def key = "$entry.key"
if(self."$key" != other."$key") {
list << [
'self': [name: key, value: self."$key"],
'other': [name: key, value: other."$key"]
]
}
return list
}
}
static List diff(Collection self, Collection other) {
([self] + [other])
.transpose()
.inject([]) {list, pair ->
def diffs = diff(pair[0], pair[1])
if(diffs) list << diffs
return list
}
}
}
I couldn't get a working assert expression for the c-d comparison. The output looks like this:
[[[self:[sku:123, size:S], other:[sku:xyz, size:S]]]]
Explanation
The DiffMixin mixin implements comparison methods for the classes you want to compare. I only implemented two, Object and Collection, but it should give you the idea. The Object comparison compares toString() output and property values. The Collection comparison basically delegates most of the work, while collecting the diffs. These methods return a list describing the differences.
Think of this as a demo :)

How to insert into mongoDB from HTML page

var productDB = new Meteor.Collection('products'); //Want to insert into this DB
var ProductParameters = nodeDB.find({"ACTIVE" : 1, "VARIENTS.ACCESS" : "PUBLIC"}, { "VARIENTS.NAME": 1, _id : 0 } ); //Taking Paramters from Another DB
Template.dpVar.events = {
'click .addProduct' : function (e) {
e.preventDefault();
ProductParameters.forEach(function(){ **//This is my Question.How to insert into productDB the key values as {ProductParameters: Val of ProductParameters}**
console.log(ProductParameters);
var pvariable = {
pvariable: tmpl.find("#ProductParameters").value
};
productDB.insert(pvariable);
});
}
};
Problem:
I have created form from the Parameters of nodeDB.
I want to store the data from this new form in a new DB productDB.
I want to run a loop where all the ProductParameters are read from nodeDB and their corresponding values inserted in form by user are pushed into ProductDB as new Entry.
EDIT:
NodeDB has Templates:
db.nodes.insert([
{
"GEOLOCATION": {
"GEO_CODE": [],
"ACTIVE_GEOLOCATION": false
},
"META": {
"CATEGORY": "levis",
"DESCRIPTION": "dsad",
"PRIVACY": "PUBLIC",
"TEMPLATE_NAME": "B",
"TEMPLATE_GROUP": "Product",
"KEYWORDS": [
"sda"
],
"CREATEDBY": "",
"SUBCATEGORY": "Blue",
"PRODUCT_TEMPLATE_TYPE": "Consumable",
"UOM": "",
"TEMPLATE_SUBGROUP": ""
},
"VARIENTS": [
{
"COMMENT": "Demo",
"INDEX": 0,
"NAME": "Brand",
"IS_PARENT": false,
"DATATYPE": "Text",
"ACCESS": "PUBLIC",
"PARENT_VARIENT": "Parem",
"TYPE": "PERMANENT"
}
]
}
])
The form is generated only from the VARIENTS
The ProductDB would be {key,value} ={VARIENTS.NAME,value from UI}
There can be multiple VARIENTS as this contains only one "Brand"
instead of
var ProductParameters = nodeDB.find({"ACTIVE" : 1, "VARIENTS.ACCESS" : "PUBLIC"}, { "VARIENTS.NAME": 1, _id : 0 } );
add .fetch() at the end
var ProductParameters = nodeDB.find({"ACTIVE" : 1, "VARIENTS.ACCESS" : "PUBLIC"}, { "VARIENTS.NAME": 1, _id : 0 } ).fetch();

exception while filtering the jqgrid when row count in the grid is zero

How to avoid getting a exception from jQgrid when the row count is zero and filters are applied. my code looks like this
function filterGrid(grid, siteId, buildingId, cityId, selectedType) {
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1; //January is 0!
var yyyy = today.getFullYear();
if (dd < 10) { dd = '0' + dd } if (mm < 10) { mm = '0' + mm } today = mm + '/' + dd + '/' + yyyy;
if (cityId == -1) {
grid.setGridParam({ search: false });
}
else {
var filter = { groupOp: "AND", rules: [{ field: "CityID", op: "eq", data: cityId}] };
if (siteId >= 0)
filter = { groupOp: "AND", rules: [{ field: "CityID", op: "eq", data: cityId }, { field: "SiteID", op: "eq", data: siteId}] }; // , { field: "BuildingID", op: "eq", data: buildingId}
if (buildingId >= 0)
filter = { groupOp: "AND", rules: [{ field: "CityID", op: "eq", data: cityId }, { field: "SiteID", op: "eq", data: siteId }, { field: "BuildingID", op: "eq", data: buildingId}] };
if (selectedType == "Outstanding Books")
filter = { groupOp: "AND", rules: [{ field: "CityID", op: "eq", data: cityId }, { field: "SiteID", op: "eq", data: siteId }, { field: "BuildingID", op: "eq", data: buildingId }, { field: "IsReturnDateNull", op: 'eq', data: true }, { field: "DueDate", op: 'gt', data: today}] };
//For filtering
grid.setGridParam({ search: true, postData: { filters: JSON.stringify(filter)} });
//For searching
//grid.setGridParam({ search: true, postData: { searchOper: "eq", searchField: "Status", searchString: selectedVal} });
}
grid.trigger("reloadGrid");
}
The Code that i have written works perfectly fine BUT if the datasource has no records to bind with the grid then i get an exception, I thought of getting the row count into a hidden field on the server side and on the client side if the row count is zero in the hidden field then skip searching, but since the datasource is getting assigned to the jqgrid during an asynchronous call back hence value in the hidden field is not getting updated(always get empty string in hiddenfield on client side) so can any body help me how to avoid getting a null exception from the jqgrid when there is no data bound to it.
I finally found an answer to this question. I used the event onsearching of the jqgrid and on the server side i get the row count from a hidden field that contains the current row and if the row count is 0 then i cancel the search operation.
protected void grdBookTransaction_Searching(object sender, Trirand.Web.UI.WebControls.JQGridSearchEventArgs e)
{
if (string.IsNullOrEmpty(GridCount.Value) || GridCount.Value == "0")
{
e.Cancel = true;
}
}

Resources