Pass array to function or make sure it is within scope? - javascript

I am trying to sort an array using an onclick function, and I'm getting the error obj is not defined. Maybe it's not within the scope?
js file:
function pageLoad() {
var url = API_URL + "/api/Ticket/GetTickets";
var data = Ajax.getData(url);
var obj = [];
var tickets = JSON.parse(data.JsonResult);
obj.Tickets = tickets;
Tickets.Data = obj;
var viewModel = {
theObject: [obj.Tickets]
};
ko.applyBindings(viewModel);
}
function SortColumn(column) {
obj.Tickets.column.sort();
}

Yes, it is a scoping issue. Move your obj declaration outside the functions, that way it will be visible to both.
Something like this:
var obj = []; // <-- move here
function pageLoad() {
var url = API_URL + "/api/Ticket/GetTickets";
var data = Ajax.getData(url);
var tickets = JSON.parse(data.JsonResult);
obj.Tickets = tickets;
Tickets.Data = obj;
var viewModel = {
theObject: [obj.Tickets]
};
ko.applyBindings(viewModel);
}
function SortColumn(column) {
obj.Tickets.column.sort();
}
EDIT:
I'm not sure if you're aware, but [] is shorthand for an Array. If what you're trying to create is an Object, then you should change your assignment to var obj = {};

Of course obj is not within scope. It's not in global scope and you aren't passing it into the function.
you can use #smaili's answer as a fix or you can pass obj to the function.
function sortColumn(obj, column) {
obj.Tickets.column.sort();
return obj;
}
Then you'll call it with both arguments.
var sortedObj = sortColumn(obj, column);
Further explanation of scoping in Javascript

Related

Copy object functions and properties in new object by value not by reference - javascript

I want to copy the functions and properties of an object into new object. The old object should not effect by changing made in new Object.
Here is the object definition:
var Call = function() {
this.number="123";
}
Call.prototype.function1 = function() {
return this.number;
}
var callobj = new Call();
I can access function1 using callobj.function1().
What I have tried to copy it:
Javascript:
var newcallobj = Object.assign({}, callobj);
In this case, i am not able to access function1 but i can access number property directly.
JQUERY:
var newObj = jQuery.extend(true, {}, callobj); OR
var newObj = jQuery.extend({}, callobj);
In this case, i am able to access function1 and property but when i change number like that newObj.number="222". It also change the value of original object.
I know that there is couple of other posts. But all is not working for me. Please let me know if i am doing any thing wrong?
AFTER #gurvinder372 answer(I am updating question):
After #gurvinder372 answer. It is working for first level of property but if it has another object like i show below and i change the value of property of another object. Then it is effecting on original object also.
var ABC = function(){
this.number = "333";
}
var Call = function() {
this.number="123";
this.anotherobj = new ABC();
}
Call.prototype.function1 = function() {
return this.number;
}
var callobj = new Call();
var newcallobj = Object.create(callobj);
newcallobj.anotherobj.number= "123";
console.log(newcallobj.anotherobj.number);
console.log(callobj.anotherobj.number);
Output of both is 123. #gurvinder372. can you check th above code ?
Object.assign only copies the enumerable properties of an object.
Use Object.create instead of Object.assign
var newcallobj = Object.create(callobj);
var Call = function() {
this.number="123";
}
Call.prototype.function1 = function() {
return this.number;
}
var callobj = new Call();
var newcallobj = Object.create(callobj);
console.log(newcallobj.function1());
Ok. By the help of #gurvinder372. The following solution is working for me.
var ABC = function(){
this.number = "333";
}
var Call = function() {
this.number="123";
this.anotherobj = new ABC();
}
Call.prototype.function1 = function() {
return this.number;
}
var callobj = new Call();
var newcallobj = Object.create(callobj);
newcallobj.anotherobj = Object.create(callobj.anotherobj);
newcallobj.anotherobj.number= "123";
console.log(newcallobj.anotherobj.number);
console.log(callobj.anotherobj.number);
Please let me know if there is any better solution other than this?

How does angular or js return data without specifying a parameter name

The title doesnt really explain what i am trying to ask here. Well here is an example:
.factory('Story', function($http) {
var storyFactory = {};
Factory.getStory = function() {
return $http.get('/api');
}
})
.controller('StoryController', function(story) {
var vm = this;
Story.allStory()
.sucess(function(mydata) {
})
})
So how allStory() returns data into mydata?
Are you asking about the way javascript replaces the written code with the logical object at the time?
eg.
console.log(new Array({"getWalkDetails":function(){return {"MaxSpeed":15, "DistanceWalked": 123}} },
"walking on sunshine",
"oh oh" ).shift().getWalkDetails().MaxSpeed);
//outputs "15" to the console
This can be rewritten as
var arr = new Array();
var func = function(){
var details = new Object();
details.MaxSpeed =15;
details.DistanceWalked = 124;
return details;
}
var obj = {"getWalkDetails" : func};
arr.push(obj);
arr.push("walking on sunshine");
arr.push("oh oh");
var firstItem = arr.shift();
//the array function 'shift()' is used to remove the first item in the array and return it to the variable
var walkingDetails = firstItem.getWalkingDetails()//same as func() or obj.getWalkingDetails()
console.log(walkingDetails.MaxSpeed);//15
As you can see we stored most of the the interpreted outputs as variables to be used seperately.
EDIT:
If you are asking how to pass objects by reference in javascript to allow the mydata variable to receive any changes done to it in the function it is passed to. then this question might be helpful to you:
javascript pass object as reference
EDIT:
edited the code above a bit more
I'm not entirely sure either what you mean (especially because I never worked with Angular), but I have a feeling you're puzzled by this little trick:
//+ fn -> [a]
var getParameterNames = (function () {
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,
ARGUMENT_NAMES = /([^\s,]+)/g;
return function (fn) {
var fnStr = fn.toString().replace(STRIP_COMMENTS, ''),
names = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
return names || [];
};
})();
function add (x, y) {
return x + y;
}
console.log(getParameterNames(add)); // => ['x', 'y']
Edit: And here's a jsfiddle.

Extend the properties returned by a function?

I'm a JS beginner. I have defined a function on my Backbone model as follows.
myFunction: function () {
return {
firstAttr: this.model.get('value-attribute')
};
}
It is available to me as this.myFunction.
From somewhere else in the code, I want to extend this.myFunction to return another attribute. In other words, I'd like it to return a dict with two attributes: { firstAttr: 'something', secondAttr: true }.
How can I do this?
I've tried:
this.myFunction().secondAttr = true;
but I know that's the wrong thing to do.
Assuming your model prototype looks like
var MyModel = Backbone.Model.extend({
myFunction: function () {
return {
// I assume you work directly on a model
// the principle would be the same with a wrapper object
firstAttr: this.get('value-attribute')
};
}
});
you can either mask your method on a model by model basis like this:
var m = new MyModel({'value-attribute': 'attr, the first'});
console.log(m.myFunction());
m.myFunction = function () {
var res = MyModel.prototype.myFunction.call(this);
res.secondAttr = true;
return res;
};
console.log(m.myFunction());
See http://jsfiddle.net/V8zt2/ for a demo
Or dynamically modify your prototype to alter all instances :
var f = MyModel.prototype.myFunction;
MyModel.prototype.myFunction = function () {
var res = f.call(this);
res.secondAttr = true;
return res;
};
var m = new MyModel({'value-attribute': 'attr, the first'});
console.log(m.myFunction());
http://jsfiddle.net/V8zt2/1/
How about modifying your myFunction to :
myFunction : function () {
var i,
obj = {};
for (i=0; i< arguments.length;i++){
obj['attribute'+(i+1)] = this.model.get(arguments[i]);
}
return obj;
}
This way you can send keys of model, that you want to be in the returned object as arguments to myFunction.

Javascript: Modify array directly only within its own function

I have a very simple function:
var errorsViewModel = function () {
var self = this;
var _errors = ko.observableArray([]);
self.get = function () {
return _errors;
};
self.insert = function ( error ) {
_errors.push(error);
};
}
What I want to acomplish is make _errors array modifiable directly only within its own function. That is users from outside can get the array for reading through the get method and insert itsert items only through the insert method.
But not to be able to do something like this:
var err = new errorsViewModel();
var array = err.get();
array.push('item');
Instead use the errorsViewModel interface :
err.insert('some error');
Is that possible?
Just copy the returned array:
self.get = function () {
return _errors.slice(0);
};
That way, when get is called, the caller can make changes to it if they want - but it won't modify the original.
To make sure that your array isn't accessible from outside your scope I would suggest that you expose the array via a ko.computed and then notify it's listeners on an insert.
var errorsViewModel = function () {
var self = this;
var _errors = [];
self.errors = ko.computed(function () {
return self.get();
});
self.get = function () {
return _errors.splice(0);
};
self.insert = function ( error ) {
_errors.push(error);
self.errors.valueHasMutated();
};
}

Javascript module pattern, nested functions, and sub modules

I am trying to wrap my head around javascript modules, but I'm unsure how to split up a module into further sub modules. I have read that nested functions are not really a great idea, due to performance, so how do I break up a function in a module? For example, lets say I have the following module:
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
// This is where I need to define a couple smaller functions
// should I create a new module for bigFunction? If so, should it be nested in Editor.build somehow?
}
};
})();
bigFunction is only related to Editor.build. Should I attach the smaller functions that make up bigFunction to the prototype bigFunction object? I'm not even sure if that would make sense.
var Editor = {};
Editor.build = (function () {
var x = 100;
return {
bigFunction: function () {
bigFunction.smallFunction();
bigFunction.prototype.smallFunction = function(){ /*do something */ };
// not sure if this even makes sense
}
};
})();
Can someone please throw me in the right direction here? There is so much misleading information online, and would just like a definite guide on how to deal with this sort of modularization.
Thank you.
Here is a snippet I use to make names for an input:
var dynamicCounter = 0;
//custom dropdown names
var createContainerNames = function () {
function Names() {
this.id = "Tasks_" + dynamicCounter + "__ContainerId";
this.name = "Tasks[" + dynamicCounter + "].ContainerId";
this.parent = "task" + dynamicCounter + "Container";
}
Names.prototype = { constructor: Names };
return function () { return new Names(); };
} ();
And then I use it:
var createdNames = createContainerNames();
var createdId = createdNames.id;
dynamicCounter++;
var differentNames = createContainerNames();
var differentId = differentNames.id;
Another approach would be to do this:
var NameModule = function(){
//"private" namemodule variables
var priv1 = "Hello";
//"private namemodule methods
function privMethod1(){
//TODO: implement
}
//"public namemodule variables
var pub1 = "Welcome";
//"public" namemodule methods
function PubMethod(){
//TODO: pub
}
return {
pub1 : pub1,
PubMethod: PubMethod
};
and then to use it
var myPubMethod = new NameModule();
myPubMethod.PubMethod();
var pubVar = myPubMethod.pub1;
EDIT
You could also take this approach:
var mod = function(){
this.modArray = [];
};
mod.prototype = {
//private variables
modId: null,
//public method
AddToArray: function (obj) {
this.modArray.push(obj);
}
}

Categories

Resources