Backbone set method, pass a variable as the key? - javascript

Im trying to pass an argument which would dynamically set the key in the backbone set method.
I pass it as a string into the constructor of my function like this
this.keyStat('points', 1)
That passes points, but when I set the model it creates the attribute stat not recognizing it as a variable.
keyStat: function(stat, number) {
var addStat = parseInt(this.model.get(stat)) + number;
console.log(this.model.set({stat: addStat}));
}
I am trying to build this function so that I dont have to repeat a lot of code and bloat my project, but I am not sure how I can pass that into the set method so that it recognizes my argument.
My question is how do I pass an argument/variable to the backbone set methods key?

set method can take a key as a first argument and value as a second (unless first argument is an object)
keyStat: function(stat, number) {
var addStat = parseInt(this.model.get(stat)) + number;
console.log(this.model.set(stat, addStat));
}

Related

Creating a method with a parameter and when called can accept a parameter or not accept

I have the method below in a react application. This method accepts a parameter.
const displayModal = (p:Result) => {
setConfirm(true);
if(p) { //check variable for truthy
setSelectedRow(p);
}
}
I want to be able to call this method with or without a parameter.
If I call the method without passing a parameter my code does not compile
displayModal()
How can I write this such that I will be able to use the method
without passing a parameter as well.
Assuming you are using TypeScript, you can simply specify an optional or default parameter.
Either:
// optional
const displayModal = (p?:Result) => {}
or:
// default
const displayModal = (p:Result = new Result()) => {}
// new Result() can be anything that makes sense
They both let you call the method without providing a parameter.
The only real difference between the two is for optional, and the value would be undefined in the method. For default, the value would be your default value.

How to assign additional properties with one property in Angular

I have a Angular service and in it I have variables like this:
export class MyService {
someVariableA = 1;
someParams = {
someVariableB,
otherVariable: this.someVariableA
};
}
and in a component I set the 'someVariableA' to 3
this.myService.someVariableA = 3;
and I want 'otherVariable' to get that value 3 as well, but it doesn't. It remains 1 when I go to get the value.
let v = this.myService.someParams.otherVariable;
Is it possible to set 'otherVariable' this way or any other way via 'someVariableA'?
As #Zulwarnain answered, 1 is a number or a primitive data type. Primitive data types in javascript are passed by value, not by reference which you seem to be expecting here.
An easy fix for this is to assign a function to otherVariable instead. Now just invoke the function someParams.otherVariable() and it will return the value of someVariableA. No need to make this complicated.
export class SingletonService {
public someVariableA = 1;
public someParams = {
otherVariable: () => this.someVariableA
};
}
This is basic javascript with multiple sources covering the subject.
https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0
I concur with this answer that you will have a better time if you use a reference type like an object/array instead of a primitive value type like a number. By adding one layer of indirection (e.g., someVar = 123 becomes someVar = {value: 123}) you could very easily get similar functionality to what you're seeking.
If, however, your use case requires an object's property to directly act like a reference to a primitive value type stored somewhere else, you can get this behavior by implementing the property as a getter and setter pair. It's more complicated, but it acts the way you want.
Here's an example:
class MyService {
someVariableA = 1;
someParams: {
someVariableB: number;
otherVariable: number;
};
constructor() {
this.someVariableA = 1;
const that = this;
this.someParams = {
someVariableB: 2,
get otherVariable() {
return that.someVariableA
},
set otherVariable(val: number) {
that.someVariableA = val;
}
}
}
}
Note that in order for the otherVariable getter and setter to be able to access the right context, I had to move the code into the constructor and copy this into a new variable I called that. The this context of a getter/setter refers to the object it's a member of, and not some this from an outer scope.
Let's make sure it works:
const ms = new MyService();
ms.someVariableA = 100;
console.log(ms.someParams.otherVariable); // 100
ms.someParams.otherVariable = -5;
console.log(ms.someVariableA); // -5
Looks good; changes to ms.someVariableA are immediately reflected in ms.someParams.otherVariable, and vice versa. All right, hope that helps; good luck!
Playground link to code
You are assigning the value type this will not work like you want. you need to assign reference type
obj ={someVariableA : 1};
someParams = {
otherVariable: this.obj
};
in the above code, if you change the value of obj.someVariableA it will also change the value of someParams.otherVariable
I am expexting that you have knowledge about reference type and value types variables
click here for demo
I don't think you want to do that. I believe you are getting a new instance of the service each time you call it, so the variables get reset.
you might want to set that variable in localStorage instead, and then have the service retrieve it from localStorage. That way it will always be getting whatever it was last set to.
or just pass that variable into your service call, instead of trying to use a local service variable.

Is there a way to tell whether a function parameter was passed as either a literal or as a variable?

I have a function:
function hello(param){ console.log('param is '+param); }
And two calls. First:
hello(123)
Second:
var a=123; hello(a);
Is there any possible way to tell, from within the hello function, whether param was passed as a var or as a literal value?
NOTICE: I am not trying to solve a problem by this. There are many workarounds of course, I merely wanted to create a nice looking logging function. And also wanted to learn the boundaries of JavaScript. I had this idea, because in JavaScript we have strange and unexpected features, like the ability to obtain function parameter names by calling: function.toString and parsing the text that is returned.
No, primitives like numbers are passed by value in Javascript. The value is copied over for the function, and has no ties to the original.
Edit: How about using an object wrapper to achieve something like this? I'm not sure what you are trying to do exactly.
You could define an array containing objects that you want to keep track of, and check if its in there:
var registry = [] // empty registry
function declareThing(thing){
var arg = { value: thing } // wrap parameter in an object
registry.push(arg) // register object
return arg; //return obj
}
function isRegistered(thingObj){
return (registry.indexOf(thingObj) > -1)
}
var a = declareThing(123);
hello(a);
function hello(param){
console.log(isRegistered(param));
}

Cast a javascript object into a model of the controller

I created an object in my js file:
function Shape(name, color, count) {
this.Name = name;
this.Color = color;
this.Count = count;
}
var apples = new Shape('apple', 'green', 5);
I want to pass this "class" into the controller via load'function, so I wrote:
$('#myDiv').load(url, { 'Shape': apples });
The url is the url of a function in the controller:
function GetShape(shape as ShapeModel) as actionResult
End Function
While ShapeModel is:
Class ShapeModel
Public Property Name As String
Public Property Color As String
Public Property Count As Integer
Public Property IsHot As Boolean
End Class
The function is called by the load function but the parameters of the class are equal to nothing.
I want to convert the class that came in the js file (Shape) into the class in the controller(ShapeModel) In the function above (GetShape).
These classes have the same properties, except one property (IsHot).
How can I do it?
I tried to send the class of the js as JSON.stringify and then make a deserialization in the controller from the given string into the class of ShapeModel, but the deserializtion failed..
The optimal solution is to send it as a class and not stringify that..
Any help appreciated!
I believe that your issue is in how you are passing the parameters in the jQuery load call. You are wrapping your Shape object in another object with a Shape property. Instead, just pass the Shape object directly as the data.
$('#myDiv').load(url, apples);
I think that MVC only supports binding a single parameter from the body, so you don't need to have something that specifies the parameter name.

Calling javascript function with arguments using JSNI

I'm trying to integrate Mixpanel with GWT, but I have problems calling an event with a property and one value.
My function to track an simple event (without values):
public native void trackEvent(String eventName)/*-{
$wnd.mixpanel.track(eventName);
}-*/;
It works.
But when I want to add some properties and values, it doesn't work properly:
public native void trackComplexEvent(String eventName, String property,
String value)/*-{
$wnd.mixpanel.track(eventName, {property:value});
}-*/;
I have 2 problems with this:
1) Mixpanel says the property name is: "property"(yes, the name of the variable that I'm passing, not the value).
2) Mixpanel says the value is:undefined
An example from mixpanel web is:
mixpanel.track("Video Play", {"age": 13, "gender": "male"});
So, I guess the problem is I'm doing a wrong call or with wrong type of arguments.
your problem is, that when you pass the you create the property object, you don't create a parameter, taken from your property name, but rather a property named property. If you debug your code, you can check, that a parameter property is passed to your mixpanel.track function.
To do what you want, you have to use an other syntax.
public native void trackComplexEvent(String eventName, String property,
String value)/*-{
//create the property object you want to pass
var propertyPassed = {}
// set the value you want to pass on the propertyPassed object
propertyPassed[property] = value;
//call your function with the argumetn you want to pass
$wnd.mixpanel.track(eventName, propertyPassed);
}-*/;
I tested your code, by creating a JavaScript funciton on my site:
window.mixpanel = {
track : function(eventName, props) {
alert(props.age);
}
}
and calling it with
trackComplexEvent("hallo", "age", "13");
The alert was '13'
BR,
Stefan

Categories