Store reference to a variable with a primitive value - javascript

I would like to write a function with a signature like
broadcast(centerPiece.rotation.y);
which stores the passed variable and publishes the value at the variable on all animation frames there after.
The issue is that I'm mostly interested in broadcasting primitive values, meaning the function above grabs the primitive value at the moment of the function call and keeps broadcasting that fixed value.
Currently I'm using this workaround
broadcast = function(obj,prop){
doBusinessLogicWith(obj[prop])
}
giving me a rather ugly signature in my code looking like
broadcast(centerPiece.rotation,'y');
This currently works because universally I will only need to broadcast properties on objects, but ... it's a little ugly. Do I have better options for tracking a variable storying a primitive value?

One slightly less ugly option might be to pass in a reference to a function that gets the current value. Something like:
broadcast = function(getValue){
var curVal = getValue();
doBusinessLogicWith(curVal);
}
Then call it with:
broadcast(function ()
{
return centerPiece.rotation.y;
});

Related

RxJS 5 Observable and variable scope aka Why is my variable unreadable

Angular 2 RC4 app written in TypeScript 1.9 and RxJS 5 beta 6
I'm having a really hard time understanding why my class variable is not passed to the Observable generating function when I subscribe. My code is below but you can see it running at this Plunker (see app/app.component.ts
//this is the problematic var. Can't pass its updated value to the Observable
input = 'nothing'; //<- default value
ngOnInit(){//<- this runs right after class constructor
//set to the value we want to send to the server
this.input = 'something';
}
start(){
//to make sure input = something when we subscribe
this.print("Subscribing when input = "+this.input);
this.source.subscribe(d=>this.print(d));
}
//Simulate sending input to the server
source = this.queryServer(this.input)
.do(()=>this.print('Emitting new value...'));
//server just returns what it received
queryServer(input){return Observable.from(['Server sees '+input])}
print(value){this.log.push(value);}
log=[];
output when I start the subscription by calling start()
Subscribing when input = something
Emitting new value...
Server sees nothing
How come even though the class property is something when we call subscribe, nothing is passed to queryserver()? I tried making input an object such as input={d:'something'} thinking that maybe the problem had to do with passing values instead of references but the result was the same.
It's happening because you are passing the default value of input to queryServer when you construct the component. Even though you change it in ngInit it has already been used to construct the pipeline that you then subscribe to. You are essentially doing the following:
this.input = "nothing";
const copyOfInput = this.input;
this.input = "something";
console.log(copyOfInput); //-> nothing
You have changed what this.input is pointing at but copy of it you made still points to the old value. I would posit that you actually want to initialize the pipeline in ngInit and not as part of the construction of the object.
Thanks to #paulpdaniels for the helpful input. He suggested that I compose the source in ngOnInit, after I have set input=something. That works for the first value of input but in practice input will continue to change after ngOnInit is complete, so the source will once again emit obsolete data.
What still really surprises me is that even when the input is an object (rather than a simple string), the problem in the OP persists. Since objects are assigned by reference in JS, I expected differently.
The code design I opted for is to compose source inside a setter for input. That way, each time that value is set, source is refreshed:
source:Observable<any>;
_input = 'nothing';
get input(){return this._input;}
set input(val){
this._input = val;
source = this.queryServer(val)
.do(()=>this.print('Emitting new value...'));
}
Still feels hack-y to me but I'm brand new to Observables so maybe there is no better way. If there is, I hope someone will teach it to me.

AngularJS: Filter function created by a function doesn't see updated scope

I'm trying to write a generic filter function like this:
var filterGenerator = function(ids) {
return function (o) {
return _.contains(ids, o.id); // using lodash _.contains
}
}
I expose this on the scope like so:
$scope.myFilter = filterGenerator($scope.listOfIds);
It works on initial page load in the partial (using o in objects | filter:myFilter), but when $scope.listOfIds changes, I would expect the filtered values to change as well - however, they do not. I suspect that when I call filterGenerator($scope.listOfIds), the returned lambda is getting a separate scoped version of $scope.listOfIds that never changes, but I'm unsure how to get around this. How would I go about making sure that the lambda sees any changes to the list?
You're right, the filter is taking the value of $scope.listOfIds at the time it is run, and then won't update because that line of code doesn't run again.
You should have the filter take listOfIds as an argument, then pass that argument in the view.
https://stackoverflow.com/a/16227326
ng-repeat="o in objects | filter:myFilter:listOfIds"
After working with Mr. Baritonehands, we decided on a better solution: We can set a particular filter on the fly like this:
$scope.filterFn = function(o) {
return filterGenerator($scope.listOfIds)(o);
}
That way the generated function always sees what's current on the scope.

JavaScript: how to pass object value from one function to another

I am using code lines like the following in order to fetch data from an intranet website:
util.setProp(obj, "firstNameOld", $(msg).find('#fname_a').text());
Now I have another function in the same file where I want to use the above again, resp. the value of that object - currently I am hard-coding this ('Test') for test purposes:
util.setProp(obj, "firstNameNew", 'Test');
How can I pass the value from the firstNameOld object in one function to the firstNameNew object in another function ? If a solution with global variables is better here than this would work as well.
Many thanks for any help with this, Tim.
I've never used the framework that includes util But I imagine that if there is a setProp() then there has to be a getProp() or something similar.
If so, you could do something like
util.setProp(obj, "firstNameNew", util.getProp(obj, "firstNameOld"));
This also relies on the assumption that you want to copy from two properties in the same object.
If not, then pass the desired source object in the getProp() call.
My guess is that functions (or properties) are called "firstNameOld" and "firstNameNew", so the first time you get it from selector, second time you want to do the same.
Try to use the local variable like that:
var text = $(msg).find('#fname_a').text();
//
util.setProp(obj, "firstNameOld", text);
//
util.setProp(obj, "firstNameNew", text);

AngularJS - Change the $scope object

I have a very weird issue.
I have an object under the $scope
I using an angular.foreach loop but there is a problem.
when I'm trying to set a value depending on langKey(where langKey is 'en' or 'el') all the values are being updated by ingoring the langKey.
$scope.finalObject[langKey]['servicesElements'][itemKey]['name'] = something;
the problem still exists when I simply use the console in order to change the values from there.
I'm setting the value 'myCustomText' to the el version of the object
$scope.finalObject.el['servicesElements'][itemKey]['name'] = 'myCustomText'
BUT if i run this one
$scope.finalObject.en['servicesElements'][itemKey]['name']
it returns 'myCustomText' with no reason because what I changed was the el version not the en.
Is this normal? I'm totally stuck
Thank you in advance
Well guys,
The problem was that I had declared the two different objects with the same source.
$scope.finalObject.el.servicesElements = something;
and
$scope.finalObject.en.servicesElements = something
I didn't have seen that before, but the browser was behaving like I have typed
$scope.finalObject.en.servicesElements = $scope.finalObject.el.servicesElements = something
and in every change of the one the other was following.
(in php is called pointer)
The solution was to use the angular's copy function
http://docs.angularjs.org/api/angular.copy
So I simply used this SO answer Reset a model with angular.js did this
$scope.tmpVar = something;
$scope.finalObject.en.servicesElements = angular.copy($scope.tmpVar);
$scope.finalObject.el.servicesElements = angular.copy($scope.tmpVar);

Programatically output variable and object names as literal text strings

I'd really like to track variables without switching between Firebug console windows or clicking around so much, so I want to draw a runtime viewer of variable names and their corresponding values that will display on the page of the app I am building.
I'd like to two functions, show(variableName) and freeze(variableName). They will output both the variable's value and the name of the variable or object as a literal string which will serve as the text label in the viewer. freeze(variableName) is the same as show(variableName) except with a setTimeOut timer for tracking loops.
I'm sure I'm missing something basic, but I haven't found out a way to get the string that comprises the name of a value programmatically so I can use it as a label. I guess I could create the table with hardcoded labels prior to runtime and just populate it with values at runtime, but I really want to generate the table dynamically so it only has those variables I specifically want to show or freeze. Simple functions:
foo1 = "Rock";
show(foo1);
foo2 = "Paper";
show(foo2);
foo3 = "Scissors";
show(foo3);
should output this via getElementById('viewer-table'):
<table>\<tr><td>foo1</td><td>Rock</td></tr><tr><td>foo2</td><td>Paper</td></tr><tr><td>foo3</td><td>Scissors</td></tr></table>
I've tried this solution:
How to convert variable name to string in JavaScript?
and eval() but it's not working for me...I dunno, shouldn't this be easy? Getting frustrated...
Thanks,
motorhobo
I am not sure you can actually get the "name" of the variable that is being passed into a function for two reasons:
1) The variable is just an identifier. In fact, you could have multiple identifiers reference the exact same object. You are (generally) passing that reference, not any actual object.
2) The show/freeze function is going to stomp on the identifier name, either through named arguments in the function declaration or by referencing them through the arguments array.
I was trying to think if there was some clever way to use the arguments.callee or the stack property on an exception in Firefox... but I can't see anything that would expose the arguments as you desire.
What I would recommend is to simply add the name of the variable and its value to a simple object, and call one of the various jsDump methods (I prefer the one in QUnit):
function show(o) {
document.getElementById("viewer-table").innerHTML = QUnit.jsDump(o);
}
// actually use the method
show({"foo1":foo1});
There's no easy way to solve this as the called function simply doesn't know the original name of the variable. You couldn't solve this with reflection even (esp. in javascript) so you'll have to pass the name of the variable to the function too. To follow the link you posted:
function show(varObject)
{
for(name in varObject)
{
alert(name + ": " + varObject[name]);
// save both name and reference to the variable to a local "to observe array"
}
}
And call it with
var test = "xxx";
show({'test' : test});
Within the for loop you could add easy variable to a monitor array and update your gui in fixed time intervalls (you can't be notifed when a signle variable changes it's value. You need some kind of global monitor/observer which exactly you're trying to create).

Categories