Firebase-Polymer array code Problems - firebase-polymer

This function will be loop and every loop key1 and key2 will change... the problem is the database results which is an array will not get every data of the keys it will only record the last data.
GettingData: function(key1,key2){
var list=[];
console.log('Getting Data of '+key2);
var ref = firebase.database().ref('/users/'+key1+'/products/'+key2).orderByKey().equalTo('name');
ref.on('child_added', function(data) {
console.log(data.val());
list.unshift(data.val());
this.databaseresult = list;
console.log('Productdata of '+ key1 +' is LOADED');
console.log('pushing to array '+list);
console.log(this.databaseresult);
this.$.results.products = this.databaseresult;
}.bind(this));
},

When changing properties if you want any observers to be notified use this.set('propertyName', value);. Also when your setting this.$.results.products = this.databaseresult; with your current code nothing will update plus even if using Polymer.set method you won't be the data binding I think your expecting because that requires the use of the polymer data binding syntax IE <x-element products="{{databaseresult}}"></x-element>. At least to my knowledge, you might be able to force it manually. by calling a this.fire('databaseresult-changed'); event.
GettingData: function(key1,key2){
console.log('Getting Data of '+key2);
var ref = firebase.database().ref('/users/'+key1+'/products/'+key2).orderByKey().equalTo('name');
ref.on('child_added', function(data) {
console.log('pushing value' + data.val() + 'to ' + this.databaseresult);
this.push('databaseresult', data.val());
console.log('Productdata of '+ key1 +' is LOADED');
}.bind(this));
},
<!-- One way binding -->
<x-element id="results" products="[[databaseresults]]"></x-element>
<!-- Two way binding -->
<x-element id="results" products="{{databaseresults}}"></x-element>

Related

How to delete mass records using Map/reduce script?

I have created a Map/Reduce script which will fetch customer invoices and delete it. If I am creating saved search in UI based on the below criteria, it shows 4 million records. Now, if I run the script, execution stops before completing the "getInputData" stage as maximum storage limit of this stage is 200Mb. So, I want to fetch first 4000 records out of 4 million and execute it and schedule the script for every 15 mins. Here is the code of first stage (getInputData) -
var count=0;
var counter=0;
var result=[];
var testSearch = search.create({
type: 'customrecord1',
filters: [ 'custrecord_date_created', 'notonorafter', 'sta​rtO​fLa​stM​ont​h' ],
columns: [ 'internalid' ]
});
do{
var resultSearch = testSearch.run().getRange({
start : count,
end : count+1000
});
for(var arr=0;arr<resultSearch.length;arr++){
result.push(resultSearch[arr]);
}
counter = count+counter;
}while(resultSearch.length >= 1000 && counter != 4000);
return result;
During creating the saved search, it is taking long time, is there any work around where we can filter first 4000 records during saved search creation?
Why not a custom mass update?
It would be a 5-10 line script that grabs the internal id and record type of the current record in the criteria of the mass update then deletes the record.
I believe this is what search.runPaged() and pagedData.fetch() is for.
search.runPaged runs the current search and returns summary information about paginated results - it does not give you the result set or save the search.
pagedData.fetch retrieves the data within the specified page range.
If you are intent on the Map/Reduce you can just return your created search. Netsuite will run it and pass each line to the next phase. You can even use a saved search where you limit the number of lines and then in your summarize phase re-trigger the script if there's anything left to do.
The 4k record syntax though is:
var toDelete = [];
search.run().each(function(r){
toDelete.push(r.id);
return toDelete.length < 4000;
});
return toDelete;
finally I normally do this as scheduled mass update. It will tend to interfere less with any production scheduled and map/reduce scripts.
/**
* #NApiVersion 2.x
* #NScriptType MassUpdateScript
*/
define(["N/log", "N/record"], function (log, record) {
function each(params) {
try {
record.delete({
type: params.type,
id: params.id
});
log.audit({ title: 'deleted ' + params.type + ' ' + params.id, details: '' });
}
catch (e) {
log.error({ title: 'deleting: ' + params.type + ' ' + params.id, details: (e.message || e.toString()) + (e.getStackTrace ? (' \n \n' + e.getStackTrace().join(' \n')) : '') });
}
}
return {
each:each
};
});

Unable to set array as environment variable - Postman test

I am trying to set an array as an environmental variable in postman.
But it stores the first value of the array rather than the array.
var aDataEntry = postman.pm.environment.get('data_set_entries');
if(aDataEntry == null) {
aDataEntry = [];
}
var jsonData = pm.response.json();
aDataEntry.push(jsonData.dataEntry.id);
// a console.log here confirms that aDataEntry is an array
postman.pm.environment.set('data_entry',aDataEntry);
As mentioned in the comment of the code, the variable is coming as an array,
but when I again get the environment variable in the second run, it is not
of type array. But just contains the first element in the array.
What's wrong here?
How can set the array and use it from the postman environment variable.
It seems like pm.environment.set calls toString to set an environment value. You can use the below code to work-around that:
var aDataEntry = pm.environment.get('data_set_entries');
if(aDataEntry == null) {
aDataEntry = [];
} else {
aDataEntry = JSON.parse(aDataEntry);
}
var jsonData = pm.response.json();
aDataEntry.push(jsonData.dataEntry.id);
// a console.log here confirms that aDataEntry is an array
pm.environment.set('data_entry',JSON.stringify(aDataEntry));
Edit 1:
As mentioned in the Postman reference docs, it is suggested that one use JSON.stringify() and JSON.parse() for storing complex objects. I have updated the code accordingly.
I'm not sure of how you intend to use the array, but to dynamically generate an array for use in a Body > raw > JSON POST, as in the answer above you do need to actually store the var as a string.
Here's an example of that and it's use in the POST Body. I had a long list of IDs, and I'm using Postman to do some bulk user profile updates.
In the Pre-request Script, generate the string to be POSTed as an array.
var externalIds = [111,222,333,444];
var attrString = "";
externalIds.forEach(userId => {
attrString += `,{"external_id": ${userId},"my_first_attribute": false,"my_next_attribute": true}`;
});
attrString = attrString.replace(',',''); // strip out that 1st unwanted comma
pm.environment.set("attributeArray",attrString);
The saved "array", Postman console logged:
"{"external_id": 111,"my_first_attribute": false,"my_next_attribute": true},
{"external_id": 222,"my_first_attribute": false,"my_next_attribute": true},
{"external_id": 333,"my_first_attribute": false,"my_next_attribute": true},
{"external_id": 444,"my_first_attribute": false,"my_next_attribute": true}"
Looks like bad, nested double quotes, but the format is actually valid.
My Body > raw looks like:
{
"api_key": "{{api_key}}",
"attributes": [{{attributeArray}}]
}
Note the Postman variable is wrapped in "[" and "]".
If my externalIds array needed to be a pm variable, I'd store that as a string, and .split() it when using it in the Script tab.
The Postman console really helps get past the syntax mistakes.

Pass variables to ember handlebars

I have an Ember.js ArrayController and some handlebar code that looks like this
<p>{{length}} {{pluralize length "thing"}}</p>
Then I've got a handlebar helper that looks like
Handlebars.registerHelper('pluralize', function(count, str){
debugger;
return (count > 1 ? str+"s" : str);
}
);
When the debugger breaks I observe seeing that count = 'length' not a number like I would expect.
So what gives? What's the correct way to accomplish my obvious task.
Working fiddle here. http://jsfiddle.net/MwTuw/2/
The trick is to use Ember.registerBoundHelper which passes all the relevant data as a final argument to the function.
Ember.Handlebars.registerBoundHelper('pluralize', function (count) {
var options = Array.prototype.pop.call(arguments);
var string = options.data.properties[1];
return (count > 1 ? string+"s" : string);
});
This removes the {{if controller.length}} hack that is required with the other solution and means that adding or removing additional objects will update the value accordingly.
How about this:
Ember.Handlebars.registerHelper('pluralize', function (property, options) {
var count = Ember.Handlebars.get(this, property, options);
var _options = options;
count = parseInt(count, 10); //to be sure ...
if (count > 1) {
_options = _options.concat('s');
}
return new Handlebars.SafeString(_options);
});
EDIT
Here is a working fiddle
EDIT 2
Here is your working updated fiddle
Basically the problem was that the handlebar helper was acting when the controller still had no records, I've added a if helper to the template that listen on the controller.length and fires when it changes and so invoking also the handlebar helper to parse the value.
Hope it helps
Using Ember.registerBoundHelper will make all the key-value pairs in the template available as an hash on the 2nd parameter of the helper:
Handlebars template:
{{orderShow dataOrderBy key1="value1" key2="value2" ... keyN="valueN"}}
Javascript:
Ember.Handlebars.registerBoundHelper('orderShow', function(order, options) {
if(options) {
for(var prop in options.hash) {
alert(prop + '="' + options.hash[prop] + '"')
}
}
return order;
}
This behaviour is described at the end of the following page: http://handlebarsjs.com/expressions.html

Jade templating "each" function returns empty object

I've had a bug that has been bugging me for days. I'm pretty new to Node and the Jade templating system so bear with me: I'm looking to add stylesheets in the following way:
App.js (Express):
app.get('/', loadUser, function(req, res) {
var User = req.user;
// console.log(User.groups[2]);
// var groups = User.groups.split(',');
// OK DUh. This only gets called when the client has the script Socket.IO
// and client runs socket.connect()
getMessages(User, function(messages) {
var locals = {
scripts: [
'https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js',
'index.js'
],
stylesheets: [
'index.css'
],
user : User,
messages: messages
};
console.log('ok');
res.render('app.jade', {locals : locals});
});
});
In layout.jade (which is executed with app.jade) I have:
!!! 5
html
head
title UI
link(rel='stylesheet', href = 'stylesheets/reset.css')
link(rel='stylesheet', href = 'stylesheets/layout.css')
- var stylesheets = stylesheets || [];
#{stylesheets}
- each stylesheet in stylesheets
- if(stylesheet.indexOf('http') >= 0)
link(rel='stylesheet', href = stylesheet)
- else
link(rel='stylesheet', href = "stylesheets/"+stylesheet )
Plus more... I keep running into the same error:
9. ' - if(stylesheet.indexOf(\'http') >= 0)'
Object function () {
var o = {}, i, l = this.length, r = [];
for(i=0; i
for(i in o) r.push(o[i]);
return r;
} has no method 'indexOf'
Now.. the gotcha is that this exact template works in another application that passes in the exact same variables: I would REALLY appreciate any suggestions you guys have on this thorny issue!
Thanks!
Matt Mueller
So here's your issue...
in this line:
res.render('app.jade', {locals : locals});
you are passing in locals ==> locals, which is a hash (ok, so I'm a PERL guy, I think JS calls them 'associative arrays')
So now inside your jade template we have the line:
- var stylesheets = stylesheets || [];
inside JADE, you have defined the variable "locals", but everything else is hidden under that, so the variable "stylesheets" is NOT defined (locals.stylesheets is defined instead). So this line of code sets the variable "stylesheets" to "[]"
So here's where I have to speculate. "indexOf" is a method of the Array object. Perhaps arrays constructed inside JADE don't have this method whereas arrays constructed in node.js DO have this method. Which would explain why you get an error trying to call "stylesheets.indexOf(...)"

CFGRID - replace data store or filter on more than one column

ColdFusion 8
I have a cfgrid that that is based on a query. It is not bound to a cfc function because I want a scrolling grid, not a paged grid (you must supply the page number and page size if you use BIND).. I can figure out how to make it filter on one column by using the following code, but I really need to filter on three columns...
grid.getDataSource().filter("OT_MILESTONE",t1);
Adding more to the filter string does not do the trick...it ignores anything more than the first pair of values..
so..I thought if I called a function that passes the three values and returned the query results to me, I could replace the Data Store for the grid..but I cannot figure out the syntax to get it to replace.
The returned variable for the query has the following format:
{"COLUMNS":["SEQ_KEY","ID","OT_MILESTONE"],"DATA":[[63677,"x","y"]]}
Any ideas?
have you looked at queryconvertforgrid()?
http://www.cfquickdocs.com/cf9/#queryconvertforgrid
Update: have you looked at these?
http://www.danvega.org/blog/index.cfm/2008/3/10/ColdFusion-8-Grid-Filtering
http://www.coldfusion-ria.com/Blog/index.cfm/2009/1/13/Playing-with-cfgrid--Filter-showhide-Columns-and-using-the-YUI-Buttons-library
http://cfsilence.com/blog/client/index.cfm/2007/8/9/Filtering-Records-In-An-Ajax-Grid
after much blood, sweat, tears and swearing..here's the answer, in case anyone else might need to filter a cfgrid by more than one variable:
var w1 = ColdFusion.getElementValue('wbs');
var t1 = ColdFusion.getElementValue('task');
var p1 = ColdFusion.getElementValue('project');
grid = ColdFusion.Grid.getGridObject('data');
store = grid.getDataSource();
store.clearFilter();
store.filterBy(function myfilter(record) {
var wantit = true;
if (trim(w1) != '') {
if(record.get('WBS_ID') != w1) {
wantit = false;
}}
if (trim(t1) != '') {
if(record.get('OT_MILESTONE') != t1) {
wantit = false;
}}
if (trim(p1) != '') {
if(record.get('PROJECT') != p1) {
wantit = false;
}}
return wantit;
});
ColdFusion.Grid.refresh('data',false);
you will need a JS trim function...
Make sure the column names are caps...