Is there a way to iterate through a javascript object's prototype variables and functions? - javascript-objects

This question is no longer applicable to what I'm trying to do because I have to declare the name of the pmp objects with a name.
I want to be able to associate an object with each prototype function for my class without doing it manually for each prototype.
I've tried seeing what's inside prototype with the following methods, but to no avail
myclass.prototype.length == undefined;
myclass.prototype.toString() == [object Object];
myclass.prototype == [object Object];
This is my code. In the following lines:
this.appear = _pmp(k8rModal.prototype._appear);
this.centerSlate = _pmp(k8rModal.prototype._centerSlate);
this.adjustToScreenResize = _pmp(k8rModal.prototype._adjustToScreenResize);
I run a function called '_pmp' that creates a PreMainPost object that appear,centerSlate & adjustToScreenResize will refer to. These objects have a .run() function that will first run the pre() functions then the main() function which is being defined by the constructor parameter and then finally the post() functions.
This is all the context:
k8r-modal.js
function k8rModal(DOMnamespace){
var _ = this._ = DOMnamespace+"_"; // for DOM namespacing
this.tightWrap=1;
this.visible = 0;
$('body').prepend('<div id="'+_+'stage"></div>');
this.stage = stage = $('#'+_+'stage');
stage.css({
'display':'none',
'width':'100%',
'height':'100%',
'position': 'fixed',
'left':'0px',
'top':'0px',
'opacity': '.6',
'background-color':'#333'
});
$('body').append('<div id="'+_+'slate"></div>');
this.slate = slate = $('#'+_+'slate');
slate.css({
'display':'none',
'width':'640px',
'height':'480px',
'position': 'fixed',
'left':'0px',
'top':'0px',
'background-color':'#eee'
});
var k8rModalInstance = this;
$('.'+_+'caller').on('click',function(){
k8rModalInstance.appear.run();
});
this.appear = _pmp(k8rModal.prototype._appear);
this.centerSlate = _pmp(k8rModal.prototype._centerSlate);
this.adjustToScreenResize = _pmp(k8rModal.prototype._adjustToScreenResize);
this.centerSlate.run();
this.word="asdf";
$(window).resize(function(){
alert(k8rModalInstance.word)
k8rModalInstance.adjustToScreenResize.run();
});
}
k8rModal.prototype._appear = function(){
this.that.visible = 1;
this.that.slate.show();
this.that.stage.show();
}
k8rModal.prototype._centerSlate = function(){
var wWidth, wHeight, slate = $(this.that.slate) ;
wWidth = $(window).width();
wHeight = $(window).height();
slate.css({
top: (wHeight/2 - ( slate.height()/2))+"px",
left: ( wWidth/2 - ( slate.width()/2 ) )+"px"
});
}
k8rModal.prototype._adjustToScreenResize = function(){
this.that.centerSlate.run();
}
(pre-main-post.js) pmp.js:
function _pmp(func){
return new pmp(this,func);
}
function pmp(that,func){
var func;
this.pre = new funcList();
this.post = new funcList();
this.main = func;
this.that = that;
}
pmp.prototype.run = function(arg){
this.pre.run(arg);
this.post.run(arg,this.main());
}
pmp.prototype.trim = function(){
this.pre = new funcList();
this.post = new funcList();
}
(an object that contains a list of functions)funcList.js:
function funcList(){
this.unique; // if a function can be
this.list=[];
}
funcList.prototype.add = function(func){
if (this.unique){
var passing = 1;
for(var i; i<this.list.length; i+=1){
if (list[i].toString == func.toString){
passing = 0;
}
}
if (passing){
this.list.push(func);
}
}else{
this.list.push(func);
}
}
funcList.prototype.remove = function(func){
for(var i; i<this.list.length; i+=1){
if (list[i].toString == func.toString){
this.list.splice(i,1);
}
}
}
funcList.prototype.clear = function(){
this.list = [];
}
funcList.prototype.run = function(arg){
for(var i; i<this.list.length; i+=1){
(this.list[i])(arg);
}
}

Only the prototypes for natives and functions are accessible to you. If myClass is a function, you can iterate over its prototype by using
for(var prop in myClass.prototype){
console.log(myClass.prototype[prop]);
}

Related

how to access function parameter value inside nested AngularJS for each loop?

I am new for AngularJS and I am trying to access function parameter value inside nested angular for each loop , but that variable gets undefined error. here is my code .
var pieChart = function (_data, _fieldName) {
var data = _data;
var cost_max = 0;
var cost_min = 99999;
angular.forEach(groupBy($scope.api_data, _fieldName), function (obj, index) {
var total = 0;
var name = '';
angular.forEach(obj, function (row, i) {
name = row._fieldName;
total += 1;
})
data.push([name, total]);
if (cost_max < obj.cost) cost_max = obj.cost;
if (cost_min > obj.cost) cost_min = obj.cost;
})
$scope.chart.data = data;
$scope.loaded = 1;
}
row._fieldName is undefined here , what was the issue ? kindly help me.
var groupBy = function (xs, key) {
return xs.reduce(function (rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
In your second angular.forEach loop, you have to replace row._fieldName with row[_fieldName].
angular.forEach(obj, function (row, i) {
name = row[_fieldName];
total += 1;
})
By writing row._fieldName, you try to get the key named _fieldName from object row instead of the real field.
Little JSFiddle

AngularJS - create object array where label is $translated

I have the following array:
vm.roles = ['ROLE1', 'ROLE2', 'ROLE3', 'ROLE4'];
and I need this form of array:
vm.translatedRoles = [{id:0, label:'Role1'}, {id:1, label:'Role2'}, ...]
Therefore I wrote this function to transfer from vm.roles to vm.translatedRoles.
My Problem now is that translatedRoles stays empty, so there are no objects in it. Does anyone know why?
function translateRoles() {
var translatedRoles = [];
for(var i = 0; i < vm.roles.length; i++) {
$translate(vm.roles[i]).then(function(text) {
var role = {};
role.id = i;
role.label = text;
translatedRoles.push(role);
});
}
return translatedRoles;
}
That can't work. $translate() returns a promise. The function passed to $translate is executed later, asynchronously, when the translations are available. So, the return statement happens before translatedRoles is populated by the function.
You need to return a promise of array, or hope that the translations are already available and use $translate.instant():
function translateRoles() {
var translatedRoles = [];
for (var i = 0; i < vm.roles.length; i++) {
translatedRoles.push({
id: i,
label: $translate.instant(vm.roles[i]);
});
}
return translatedRoles;
}

getting the inner html of a contenteditable div in angularjs

I am trying to get innerHTML of a contenteditable div via function defined in controller of angularjs but it returns undefined every time.. what are the alternatives or how can I handle this issue?
$scope.genrate_HTML=function()
{
var read_string=document.getElementsByClassName("MainPage");
//console.log(read_string);
var p_tag= '\n<p id="test"> \n'+read_string.innerHTML+'\n </p>';
//document.getElementById("createdHTML").value = p_tag ;
//$compile( document.getElementById('createdHTML') )($scope);
}
the contenteditble div's classs name is "MainPage"
VisualEditor.controller("GenrateHTML",function($scope){
$scope.savefile=function()
{
$scope.genratedHTML_text=document.getElementById("createdHTML").value;
var text_file_blob= new Blob([$scope.genratedHTML_text],{type:'text/html'});
$scope.file_name_to_save=document.getElementById("file_name").value ;
var downloadLink=document.createElement("a");
downloadLink.download=$scope.file_name_to_save;
downloadLink.innerHTML="Download File";
if(window.URL!=null)
{
downloadLink.href=window.URL.createObjectURL(text_file_blob);
}
else
{
downloadLink.href = window.URL.createObjectURL(text_file_blob);
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
}
downloadLink.click();
}
function destroyClickedElement(event)
{
document.body.removeChild(event.target);
}
$scope.toggleModal = function(){
$scope.showModal = !$scope.showModal;
};
///add details
$scope.details=[];
$scope.addDetails=function(){
$scope.details.push({
Title:$scope.Details_Title,
meta_chars:$scope.Details_metaChars,
version:$scope.Details_version,
Auth_name:$scope.Details_AuthName,
copyRights:$scope.Details_copyRights
});
document.getElementById("createdHTML").innerHTML = $scope.details;
};
$scope.$watch('details', function (value) {
console.log(value);
}, true);
/////////////////////
$scope.genrate_HTML=function()
{
var read_string=document.getElementsByClassName("MainPage");
//console.log(read_string);
var p_tag = '';
for (var i = 0; i < read_string.length; i++) {
p_tag += '\n<p id="test_"' + i + '> \n' + read_string[i].innerHTML + '\n </p>';
document.getElementById("createdHTML").value = p_tag;
}
//$compile( document.getElementById('createdHTML') )($scope);
}
});
getElementsByClassName returns an Array, so, your read_string variable is an Array type. you should iterate through the elements of read_string with for loop.
NOTE: Please check the p element's id here aswell. Because id must be unique!
$scope.genrate_HTML = function() {
var read_string = document.getElementsByClassName("MainPage");
var p_tag = '';
for (var i = 0; i < read_string.length; i++) {
p_tag += '\n<p id="test_"'+i+'> \n'+read_string[i].innerHTML+'\n </p>';
}
/* Other code here... */
}
UPDATE: Don't use the code below! If read_string returns with no elements than your code will crash!
But if it's a 1 element Array then you can take the value like:
$scope.genrate_HTML = function() {
var read_string = document.getElementsByClassName("MainPage");
var p_tag= '\n<p id="test"> \n'+read_string[0].innerHTML+'\n </p>';
/* Other code here... */
}
I hope that helps. If it doesn't then paste the full code of the Controller.

javascript: when declaring a prototype method: error is invalid left hand side for assignment

I am new to object oriented javascript. Trying to make an object constructor.
Here is my code
function Collection() {
this.ports = build_ports_collection();
this.all_things = build_things_collection();
this.added_things = function() {
this.added_things.total_added = 0;
var temp = this.all_things;
temp.splice($(sth).val(), 1);
this.added_things.all = temp;
};
};
Collection.ports.prototype.reload = function() {
Collection.ports = build_ports_collection();
};
Collection.all_things.prototype.reload = function() {
Collection.all_things = build_things_collection();
};
Collection.added_things.all.prototype.reload() = function() {
var temp = Collection.all_things;
temp.splice($(sth).val(), 1);
Collection.added_things.all = temp;
};
Collection.added_things.prototype.add_things = function() {
this.added_things.total_added++;
add_things();
};
Collection.added_things.prototype.remove_things = function() {
this.added_things.total_added--;
remove_things();
};
I am getting error in the line Collection.added_things.all.prototype.reload()=....
netbeans reports: invalid left hand side for assignment.
here my intention was to bind a method reload() to Collection.added_things.all so that it will be shared among all instances of Collection
What point i am missing ?
Not sure if this is the answer you're looking for, but this came to mind.
Collection.added_things.all.prototype.reload() = function() {
var temp = Collection.all_things;
temp.splice($(sth).val(), 1);
Collection.added_things.all = temp;
};
There, you are assigning stuff to the prototype of Collection.added_things.all, while
this.added_things = function() {
this.added_things.total_added = 0;
var temp = this.all_things;
temp.splice($(sth).val(), 1);
this.added_things.all = temp;
};
is the first to declare the .all on Collection.added_things - basically, you are trying to assign a value to a property/variable/pointer that does not exist until added_things is first called.

Using javascript prototype function to initialise variable in 'this' context

I'm finding it difficult to explain in words, so here's a snippet of code I'm trying out but Firefox/firebug goes into tailspin!
I'm trying to follow this and this as a guide. What I'm trying to do here is
new MyObject.Method('string',optionsArray);
optionsArray items are iterated and saved using the prototype function Set()
if(typeof(MyObj) == 'undefined') MyObj= {};
MyObj.Method = function initialise(id,options)
{
this.id = id;
this.options = options;
this.properties ={};
for (var i = 0; i < this.options.length; i++) // =>options.length=2 (correct)
{
var obj = this.options[i];
//get the keynames, pass with values to Set() to update properties
for (var keys in obj)
{
console.log(keys); //=> correctly prints 'property1' and 'currentValue'
this.Set(keys,obj); //=> this is i guess where it enters a loop?
}
}
}
//sets properties
MyObj.Method.prototype.Set = function (name, value)
{
this.properties[name.toLowerCase()] = value;
}
and in my html page script block, i have
window.onload = function () {
var options = [
{ property1: {
show: true,
min: 0,
max: 100
}
},
{
currentValue: {
show: true,
colour: 'black'
}
}
];
var myObj = new MyObj.Method('someDivId',options);
}
please advise if I'm over complicating the code. I think checking for hasOwnProperty would help.
This should be a cleaner way of achieving what you want:
function MyObj(id, options) { // a function that will get used as the constructor
this.id = id;
this.options = options;
this.properties = {};
this.set(options); // call the set method from the prototype
}
MyObj.prototype.set = function(options) { // set the options here
for(var i = 0, l = options.length; i < l; i++) {
var obj = this.options[i];
for(var key in obj) {
if (obj.hasOwnProperty(key)) { // this will exclude stuff that's on the prototype chain!
this.properties[key] = obj[key];
}
}
}
return this; // return the object for chaining purposes
// so one can do FooObj.set([...]).set([...]);
};
var test = new MyObj('simeDivId', [...]); // create a new instance of MyObj
test.set('bla', [...]); // set some additional options
Note: For what hasOwnProperty is about please see here.
I made a declaration for MyObj and removed the function name initialise since you're obviously declaring this function to be a property of MyObj. Your final code will then be like below, and that runs for me just fine. Please note that you cannot actually call the function until after you declare the prototype function because else the object will have no notion of the Set function.
var MyObj = {};
MyObj.Method = function (id,options)
{
this.id = id;
this.properties ={};
for (var i = 0; i < options.length; i++) // =>options.length=2 (correct)
{
var obj = options[i];
//get the keynames, pass with values to Set() to update properties
for (var keys in obj)
{
console.log(keys); //=> correctly prints 'property1' and 'currentValue'
this.Set(keys,obj); //=> this is i guess where it enters a loop?
}
}
}
MyObj.Method.prototype.Set = function (name, value)
{
this.properties[name.toLowerCase()] = value;
}
var options = [
{ property1: {
show: true,
min: 0,
max: 100
}
},
{
currentValue: {
show: true,
colour: 'black'
}
}
];
var myObj = new MyObj.Method('someDivId',options);
var MyObj = {};
MyObj.Method = function initialise(id,options) {
this.id = id;
this.options = options;
this.properties = {};
for (var i = 0; i < this.options.length; i++)
{
var obj = this.options[i];
for (var keys in obj) {
this.Set(keys,obj[keys]);
//*fix obj => obj[keys]
// (and it should be singular key rather then keys
}
}
console.log(this.properties) // will output what you want
}
//sets properties
MyObj.Method.prototype.Set = function (name, value) {
this.properties[name.toLowerCase()] = value;
}
var options = [{
property1: {
show: true,
min: 0,
max: 100
}
},{
currentValue: {
show: true,
colour: 'black'
}
}];
var myObj = new MyObj.Method('someDivId',options);
this should work problem is you had your myObj = new MyObj... outside your onload event and options was out of its scope as it was declared as private variable to the anonymous function bound to the onload event.
I've fixed also the way you was copying the values to the properties as it doubled the names of the property and made it a bit messy.

Resources