Require js, must reference the required object two times - javascript

I define a script with no dependencies with require:
define([], function () {
var obj = {
doSomething: function() {}
}
return : {
obj : obj
}
});
However when I have to use doSomething like this:
require(['obj'], function (obj) {
obj.obj.doSomething();
});
What am I doing wrong, so I can't just use
obj.doSomething();

Try:
define([], function () {
var obj = {
doSomething: function() {}
}
return obj;
});

Related

"this" inside function call on another function

Function.prototype.bind = function (obj) {
const self = this;
console.log(this);
return () => {
return this.apply(obj, arguments);
};
}
MyObj1 = function () {
this.myName = 'myObj1';
}
MyObj1.prototype.who = function () {
console.log(this.myName);
}
myObj2 = {
myName: 'myObj2'
}
myObj1 = new MyObj1();
myObj1.who();
who2 = myObj1.who.bind(myObj2);
who2();
produced the following output:
myObj1
ƒ () {
console.log(this.myName);
}
myObj2
is who2 = myObj1.who.bind(myObj2); treat .who as an object and bind this to it?
looks like but still confusing to me

Angularjs retain local variable

I have a factory like this:
TestFactory= function () {
var objectName=null;
return {
SetName:function(name) {
objectName = name;
},
GetName:function() {
return objectName;
},
Init:function() {
return angular.copy(this);
}
}
}
A controller like:
TestController = function($scope) {
$scope.TestClick = function () {
var tstA = TestFactory.Init();
var tstB = TestFactory.Init();
tstA.SetName('test A')
tstB.SetName('test B')
console.log('A', tstA.GetName());
console.log('B', tstB.GetName());
}
}
In the console I get Test B for both objects.
How can I make a proper instance of this object?
I would like to use the objectName value in other functions of the factory.
Take into account that in Angular, Factories are singletons, so the instance is always the same.
You can do the following:
TestFactory= function () {
var objectName={};
return {
SetName:function(property,name) {
objectName[property] = name;
},
GetName:function(property) {
return objectName[property];
},
Clear:function(property) {
delete objectName[property]
}
}
}
Then in your controller:
TestController = function($scope, TestFactory) {
$scope.TestClick = function () {
TestFactory.SetName('a','test A')
TestFactory.SetName('b','test B')
console.log('A', TestFactory.GetName('a')); // test A
console.log('B', TestFactory.GetName('b')); // test B
}
}
Couple of issues. First your returning an object rather than a function from your factory.
app.factory('TestFactory', function() {
return function() {
var objectName = null;
var setName = function(name) {
objectName = name;
};
var getName = function() {
return objectName;
};
return {
SetName: setName,
GetName: getName
};
};
});
Then you can just instantiate like this:
var tstA = new TestFactory();
var tstB = new TestFactory();
Services and factories are singletons so I think you can achieve what you want with a more appropriate use of the factory by providing an Init function that returns the common code and unique name like so:
angular.module('app')
.factory('ServiceFactory', serviceFactory);
function serviceFactory() {
return {
Init: function (name) {
return {
objectName: name,
setName: function (name) {
this.objectName = name;
},
getName: function () {
return this.objectName;
}
};
}
};
}
This leaves the possibility to use it as a factory that can initialize many types.
You basically need to create a simple getter/setter.
angular.module('app', [])
.controller('TestController', testController)
.service('serviceFactory', serviceFactory);
testController.$inject = ['serviceFactory'];
function testController(serviceFactory) {
serviceFactory.set('A', {
name: 'test A'
});
serviceFactory.set('B', {
name: 'test B'
});
console.log(serviceFactory.getAll());
console.log(serviceFactory.get('A'));
console.log(serviceFactory.get('B'));
}
function serviceFactory() {
var
_model = {
name: ""
},
_data = {};
return {
set: function(key, data) {
_data[key] = angular.extend({}, _model, data);
},
get: function(key) {
return _data[key];
},
getAll: function() {
return _data;
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<body ng-app="app" ng-controller="testController"></body>

Acess to this from subobject in JavaScript

How do I get access to the properties or method of the main object, from sub-obiect level two (sub3). If possible I would like to avoid solutions chaining return this.
Obj = function () {};
Obj.prototype = {
name: 'name',
main: function(){
console.log(this.name);
},
subobject: {
sub2: function () {
console.log(this);
},
sub3: function () {
console.log(this.name); // How access to Obj.name ??
}
}
}
o = new Obj();
o.main(); // return name
o.subobject.sub2(); // return subobject
o.subobject.sub3(); // return undefined
With your current syntax, you can't. Because for sub2 and sub3, the this variable is Obj.prototype.subobject.
You have multiple choice:
The obvious one: don't use a suboject.
Create subobject, sub2 and sub3 in the constructor
Obj = function() {
var self = this;
this.subobject = {
sub1: function() { console.log(self); }
}
}
Use bind at each call:
o.subobject.sub2.bind(o)();

Use of functions between inner object literals in javascript

My issue is I have 2 inner objects in my js class and I'm trying to use the methods from one of those objects in my other object (examples of what I'm trying to do below). I understand why this doesn't work because of a the scope. I'm just wondering if there is a way to get it to work.
var Class1 = {
self : this,
Obj1 : {
Obj1Method : function () {
alert("Do something");
},
Obj1Method2 : function () {
alert("Do something else");
},
InnerObj1 : {
InnerNestObj1Method : function (val) {
alert(val + 2);
}
}
},
Class1Method2 : function () {
this.Obj1.Obj1Method2();
},
Obj2 : {
Obj2Method : function (val2) {
self.Obj1.InnerObj1.InnerNestObj1Method(val2);
},
Obj2Method2 : function () {
self.Class1Method2();
}
}
};
Class1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
Class1.Class1Method2(); //works
Class1.Obj2.Obj2Method2(); //No bueno
Class1.Obj2.Obj2Method(5); //No bueno
You can fix your example by replacing self with Class1.
The line self : this, is setting Class1.self to point to the global object (this when that line is evaluated).
var Class1 = {
self : this,
Obj1 : {
Obj1Method : function () {
alert("Do something");
},
Obj1Method2 : function () {
alert("Do something else");
},
InnerObj1 : {
InnerNestObj1Method : function (val) {
alert(val + 2);
}
}
},
Class1Method2 : function () {
this.Obj1.Obj1Method2();
},
Obj2 : {
Obj2Method : function (val2) {
Class1.Obj1.InnerObj1.InnerNestObj1Method(val2);
},
Obj2Method2 : function () {
Class1.Class1Method2();
}
}
};
Class1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
Class1.Class1Method2(); //works
Class1.Obj2.Obj2Method2(); //bueno
Class1.Obj2.Obj2Method(5); //bueno
What happens when you do self: this
// If this is running in non strict mode, from the global scope, `this` points
// To the global object because there was no function call setting `this`
var Class1 = {
self : this,
};
What you need to understand is that this is set by whoever called the function using this. In the example above, there is no caller, so the runtime sets this to point to the global object.
Here's how you could you could make your object a bit more reusable and give yourself a reference to the outer object:
function createClass() {
var self = {
Obj1: {
Obj1Method: function() {
alert("Do something");
},
Obj1Method2: function() {
alert("Do something else");
},
InnerObj1: {
InnerNestObj1Method: function(val) {
alert(val + 2);
}
}
},
Class1Method2: function() {
self.Obj1.Obj1Method2();
},
Obj2: {
Obj2Method: function(val2) {
self.Obj1.InnerObj1.InnerNestObj1Method(val2);
},
Obj2Method2: function() {
self.Class1Method2();
}
}
};
return self;
}
var Class1 = createClass();
Class1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
Class1.Class1Method2(); //works
Class1.Obj2.Obj2Method2(); //works
Class1.Obj2.Obj2Method(5); //works
You can do it with Classes:
"use strict"
class Class1 {
constructor() {
this.Obj1 = {
Obj1Method: function() {
alert("Do something");
},
Obj1Method2: function() {
alert("Do something else");
},
InnerObj1: {
InnerNestObj1Method: function(val) {
alert(val + 2);
}
}
};
var self = this;
this.Obj2 = {
Obj2Method: function(val2) {
self.Obj1.InnerObj1.InnerNestObj1Method(val2);
},
Obj2Method2: function() {
self.Class1Method2();
}
};
}
Class1Method2() {
this.Obj1.Obj1Method2();
}
};
var c1 = new Class1();
c1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
c1.Class1Method2(); //works
c1.Obj2.Obj2Method(3); //works
c1.Obj2.Obj2Method2(); //works

JS scope: call parent function using namespace

How do I call a parent namespace function from within a function?
var myNamespace = {
funcOne : function () {
//do something
},
funcTwo : function () {
setTimeout ( function () {
myNamespace.funcOne(); //how do I call funcOne?
}, 2000);
}
}
The usual way would be to use the this keyword inside the literal
var myNamespace = {
funcOne : function () {
//do something
},
funcTwo : function () {
var self = this;
setTimeout ( function () {
self.funcOne();
}, 2000);
}
}
But what you're doing should work just fine as well -> FIDDLE

Categories