instantiating a javascript object from its name - javascript

I am kinda implementing my own very basic MVC controller and all I want is that if I have a viewName, I want to instantiate the javascript object with the name 'viewName'. for eg.
Lets say I have an object definition as
function ViewABC() {}
ViewABC.prototype.init = function() {
alert("comes here!");
};
now somewhere in my controller module, I get a view name as 'ViewABC'. All I want is to invoke the object with the viewName
function(viewName){
//check if viewName exists somewhere! initial validation
//create var viewObj = new 'viewName' here in this case it will be
//var viewObj =- new ViewABC();
//then call viewObj.init();
I looked into window[className] as well as this[className] but neither window or this has the function class that I have defined in the context.
Please advise.

Instead of just dumping functions in the global scope, what about this:
Views = Views || {}; // namespace initialization
Views['ViewABC'] = function() {};
// ...
var viewName = 'ViewABC';
var viewObj = new Views[viewName]();
UPDATE
Change the first line to:
window.Views = window.Views || {};
or if you only use it once, just:
Views = {};

Related

How can set an outer variable value in a Javascript constructor pattern?

I have the following situation. I'm trying to create an object that will be initialized then reused over the course of a script. Part of the construction of such an object requires a login to retrieve data from a webpage. This data will be kept within the object.
Consider a file called myThingAbove.js that contains this code:
module.exports = (function(){
//need to keep these updated
var a = {}, b = {};
const myThing = function(options){
somefun(args, function(err, resp){
//stuff
a = valueBasedOnResp;
b = valueBasedOnRespAsWell;
});
})
mything.prototype.myMethod = function(args) {
// makes use of a and b
}
return myThing;
})());
I'm initializing this "object" as follows:
const myThing = require('./myThingAbove.js');
const myObj = new myThing(args);
myObj.myMethod();
It looks like I'm not able to maintain a or b's state. The constructor call with the new statement sets these values as expected but they do not persist with myObj. How can I maintain the values of these variables within my instance of myObj?
I'm using NodeJS v8.5.0.
UPDATE: It's been pointed out that myObj.myMethod() and const myObj = new myThing(args); will be executed asynchronously. This may actually be my problem. Is there a way to guarantee myObj will be constructed before myObj.myMethod() is called?

Object assignment does not work in this angularjs controller

Inside my angularjs controller, I try to assign an object into a $scope.XX object. For some reason, it cannot work. Here is a simplified version of the code inside the angularjs controller.
$scope.XXX = {};
polling_interval_ms = 100;
var poll = function (ChartObj, polling_interval_ms) {
var processedObj = {};
processedObj = processDataChart(data_Chart); //data_Chart is object that contains data that changes in real-time
ChartObj = Object.assign(processedObj);
console.log(ChartObj);
$timeout(function () {
poll(ChartObj, polling_interval_ms)
}, polling_interval_ms);
};
poll($scope.XXX, polling_interval_ms);
console.log($scope.XXX);
The strange part is the output of console.log(ChartObj); shows that data has been assigned to the object. However, the output of console.log($scope.XXX) is empty. I was expecting $scope.XXX to contain same data as ChartObj. What did I do wrong?
In javascript all parameters in function is reference. So when you change reference - you not change referenced object.
In your case you can use Object.assgin in a bit different way
Object.assign(ChartObj, processedObj);
because
The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
Or pass wrapper for object XXX, in this case it a $scope
$scope.ChartObj = {};
polling_interval_ms = 100;
var poll = function (wrapper, polling_interval_ms) {
var processedObj = {};
processedObj = processDataChart(data_Chart); //data_Chart is object that contains data that changes in real-time
wrapper.ChartObj = Object.assign(processedObj);
console.log(wrapper.ChartObj);
$timeout(function () {
poll(wrapper, polling_interval_ms)
}, polling_interval_ms);
};
poll($scope, polling_interval_ms);
console.log($scope.ChartObj);
Use
$scope.XXX
instead of ChartObj because
your are assigning value to
ChartObj
and
$scope.XXX
is not a refrence type

Use the function inside another function as the constructor in javascript

I have the function structured this way because I need to inject it as a angularjs Factory. however, when I use it stand along to create a test for it, I encounter difficutly. I can NOT reference the ItemModel inside the ItemModelGenerator! I can not create an instance of it by using it as a constructor! I tried many many ways use keyword of new or invoke both, invoke either, pass arguments in bot or either, none of them works. I am confused...
Is this possible to somehow use this ItemModelGenerator as a constructor for another var? or, let say use the ItemModel inside it to generate, but in a condition that of course, the var has to be outside of ItemModelGenerator, because it is a factory.
I tried:
var Service = new ItemModelGenerator();
Service.ItemModel();
new ItemModelGenerator().ItemMode();
new ItemModelGenerator.ItemMode();
..etc
BTW, it does work as a angularjs factory injection, its tested.
Thanks
'use strict';
function ItemModelGenerator() {
function ItemModel(inputItem) {
var defaults = {
id:'na',
name:'na'
};
var location = inputItem ? inputItem : { defaults };
this.id = location.id;
this.name = location.itemName ? location.itemName : location.name;
this.itemIsReal = this.isReal(this.id);
}
ItemModel.prototype.isReal = function(id) {
return id !== false ? true : false;
};
return ItemModel;
}
You are returning ItemModel from ItemModelGenerator when you call ItemModelGenerator. So what you get back is an ItemModel:
var ItemModel = ItemModelGenerator();
var instance = new ItemModel();
alert(instance.name);
You are returning the constructor function as the result of your wrapping function. Try:
var Service = new ItemModelGenerator()();

Returning variables in Angular JS factories?

I have the following code...
spa.factory("linkService", function() {
var currentLink = null;
return {currentLink:};
});
var cssController = spa.controller("cssController", function(linkService, currentLink) {
this.fileName = linkService.currentLink;
});
var navigationController = spa.controller("navigationController", function(linkService, currentLink) {
this.setLink = function(setValue) {
linkService.currentLink = setValue;
};
this.checkCurrent = function(checkValue) {
return linkService.currentLink == checkValue;
}
});
I've created this code from a snippet I wrote in another question, and fixed the things I was told were wrong with my first attempt. That question can be found here. This is a more specific case, and is therefore not a duplicate.
After checking the console, I believe the problem with this script lies in the factory.
The attempted function of the linkService factory is to provide a variable, currentLink which can be accessed and changed dynamically by more than one controller. The variable inside the factory I believe should be accessed by injecting the factory as a dependency into the controller function, as well as the variable.
What is the issue here?
Your linkService factory returns an object with the slot 'currentLink' and its value undefined.
You have to return the variable directly or you can return an object which references your variable or you can return an object which includes getter and setters to your variables.
The last variant has the advantage of having a nice interface defined in place.
Your code will be better readable.
spa.factory("linkService", function() {
var currentLink = "/myLink.html";
/* accessor for currentLink */
var getLink = function(){
return currentLink;
};
return {get: getLink}; // service interface
});
--- update
Some more details:
currentLink is the variable which should be accessed and which is present in the context of the linkService only
the factory returns the object "{get: getLink}" as the service. So if a controller injects the linkService, it gets this object.
Using linkService.get(); you can access the variable currentLink.
getLink is a local function only. It serves as an accessor.
The factory should return objects/methods as such:
spa.factory("linkService", function() {
var linkServiceFactory = {};
var _currentLink = null;
linkServiceFactory.currentLink = _currentLink;
return linkServiceFactory;
});
In the controller to inject it with the factory name to get its sub-parts.:
var cssController = spa.controller("cssController", function(linkService) {
this.fileName = linkService.currentLink;
});
Similarly,
var navigationController = spa.controller("navigationController", function(linkService) {
// other code.
});

Backbone.js: Model inheritance causes shared data

I've been banging my head on this one for the last two days. For some reason backbone is sharing parent instance data across inherited child models. Heres an example:
var Base = Backbone.Model.extend({
index : []
});
var Group = Base.extend({
initialize : function() {
this.index.push('from group');
}
});
var User = Base.extend({
initialize : function() {
this.index.push('from user');
}
});
var user = new User();
console.log(user.index); // ['from user']
var group = new Group();
console.log(group.index) // ['from user', 'from group']
What I'm looking for is:
console.log(user.index); // ['from user']
console.log(group.index) // ['from group']
Any insights?
Thanks!
Matt
What you are experiencing is essentially a byproduct of the way JS passes objects (or arrays) by reference and not by value. If you want index to be different for User and Group, simply instantiate it as an array in your initialize function.
var Base = Backbone.Model.extend({
initialize: function() {
this.index = [];
}
});
The index member is like a class variable in that it's in the prototype chain of Base and thus shared by all instances just as the methods it contains are also shared. Try switching the order of the instantiating User and Group. Now what does index contain? It's reverse right? That's because they are sharing everything the object passed to extend.
In order for it to be an instance variable you'll need to instantiate it in a constructor for Base, and have each subclass call that constructor from their respective constructors. Like:
var Base = Backbone.Model.extend({
initialize: function() {
this.index = [];
}
});
var User = Base.extend({
initialize: function() {
Base.prototype.initialize.call( this );
this.index.push('User');
}
});
// repeat it for group.

Categories