Constants or Final Variables in Modules Javascript - module

I am trying to write some codes which allow me to retrieve integer values based on the variable name i use. however, i am trying to make the integer values a final value or something which can't be changed. i have placed some codes below which allows me to retrieve values as explain above. can anyone tell me how issit possible for me to make them a final variable or something? Thanks in advance.
(function() {
// Create the global, and also give ourselves a convenient alias for it (`mod`)
window.MyModule = {
RED: "#FF0000",
BLUE: "#0000FF",
GREEN: "#00FF00",
};
})();
alert(MyModule.RED); // #FF0000

Disclaimer: In terms of security constant / final variables are silly. In terms of increased performance because the js engine can optimise it more I doubt it makes a difference.
Benchmark shows no noticable increase in performance. This isn't actually useful apart from pedantry or pseudo security.
The only use case is making part of your library frozen so that users don't shoot themself in the foot.
With ES5 Object.freeze
window.MyModule = Object.freeze({
RED: "#FF0000",
BLUE: "#0000FF",
GREEN: "#00FF00",
});
You can (and it's highly recommended) use the ES5-shim to upgrade older/legacy browsers for compliance.
You can also just use Object.defineProperties
window.MyModule = {};
Object.defineProperties(window.MyModule, {
RED: { value: "#FF0000" },
BLUE: { value: "#0000FF" },
GREEN: { value: "#00FF00" }
});
There is a nice shortcut for the above using Object.create
window.MyModule = Object.create(null, {
RED: { value: "#FF0000" },
BLUE: { value: "#0000FF" },
GREEN: { value: "#00FF00" }
});
Be wary that sets the prototype to null, you may want to set it to Object.prototype

The best/only way I know to do this is to declare RED, BLUE, GREEN, etc. as functions and return a constant value, like so:
window.MyModule = {
RED: function() { return "#FF0000"; },
BLUE: function() { return "#0000FF"; },
GREEN: function() { return "#00FF00"; }
};
Someone can still overwrite the function to do something different, but it's semantically more difficult to do - a function seems more so like it shouldn't be overwritten.

You can create a read-only property (i.e. one that has a getter but no setter).
If using ECMAScript5 check out Object.defineProperty().
Some earlier versions support object.__defineGetter__().

Related

Selecting edges based on both edge's data and target's data

I would like a selector for edges matching
edge[type="blocker"]
that have a target matching
node[status="complete"]
In other words, is there a valid way of expressing the following:
cytoscape({
...
style: [
...
{
selector: '( node -> node[status="complete"] )[type="blocker"]',
style: {
display: 'none',
},
},
...
],
...
})
I don't see a way of doing this in the documentation.
Obviously, I could copy the target's data into the node's data and use the following:
edge[type="blocker"][target_status="complete"]
But duplicating the data goes against my every instinct as a software developer.
You can provide function to filter method:
cy.edges().filter(function(ele) {
return ele.data('type') == 'blocker' &&
ele.target().data('status') == 'complete';
})
How about this
EDIT:
var selectedEdges = cy.nodes("[status= 'complete']").connectedEdges("[type = 'blocker']);
var selectedEdges.addClass('specialSnowflake')
And in your stylesheet, just define:
{
"selector": "edge.specialSnowflake",
"style": {
"display": "none"
}
}
If a selector does not suffice, then you could (1) suggest a new feature to enhance the edge -> selector and perhaps even make a PR for it or (2) use a function on the style property instead.
E.g. for (2):
{ selector: 'edge', style: { display: edgeIsDisplayed } }
where the function can be anything, like edgeIsDisplayed(edge) => edge.data('foo') === 'bar' && edge.target().hasClass('baz')
See http://js.cytoscape.org/#style/mappers
There's no selector that will help.
However, it is possible to avoid having to manually update two elements when data changes.
Style sheet value functions are called every time a matching element's data changes. In one those function, one could therefore update the data of incoming edges every time the node's data is updated, keeping the data of the two in sync automatically.
var push_status = function(node) {
node.incomers('edge').forEach( edge => edge.data('target_status', node.data('status')) );
node.outgoers('edge').forEach( edge => edge.data('source_status', node.data('status')) );
};
cytoscape({
...
style: [
...
{
selector: 'node',
style: {
label: node => { push_status(node); return node.data('id'); },
},
},
{
selector: 'edge[type="blocker"][target_status="complete"]',
style: {
display: 'none',
},
},
...
],
...
})
This would qualify as a hack, but it works perfectly. Updating the node's data updates the edge's data, which causes the style to be applied or unapplied as appropriate.
Be wary of creating an infinite loop! In particular, modifying the data of a node's parent will trigger a calculation of the node's style. This problem can be avoided by replacing
ele.data('key', val)
with
// Making changes to a element's data triggers a style recalculation.
// This avoids needlessly triggering the style recalculation.
var set_data = function(node, key, new_val) {
let old_val = node.data(key);
if (new_val != old_val)
node.data(key, new_val);
};
set_data(ele, 'key', val)

React Native Animated singleValue.stopTracking is not a function

I have the following code to animate in React Native
Animated.timing(
this.state.absoluteChangeX,
{toValue: 0},
).start(function() {
this.lastX = 0;
this.lastY = 0;
});
Pretty simple, but whenever it's triggered, I receive the error:
singleValue.stopTracking is not a function
Here's where the error originates:
/react-native/Libraries/Animates/src/AnimtaedImplementation.js
var timing = function(
value: AnimatedValue | AnimatedValueXY,
config: TimingAnimationConfig,
): CompositeAnimation {
return maybeVectorAnim(value, config, timing) || {
start: function(callback?: ?EndCallback): void {
var singleValue: any = value;
var singleConfig: any = config;
singleValue.stopTracking(); // <--------------- HERE!!!
if (config.toValue instanceof Animated) {
singleValue.track(new AnimatedTracking(
singleValue,
config.toValue,
TimingAnimation,
singleConfig,
callback
));
} else {
singleValue.animate(new TimingAnimation(singleConfig), callback);
}
},
stop: function(): void {
value.stopAnimation();
},
};
};
I'm not extremely versed in typeScript, but var singleValue: any means that "singleValue" could be any type. In my case, it's a number. Since numbers don't have methods, it would make sense that this would error.
Am I doing something wrong?
The value you wish to animate must be an instance of Animated.Value, or one of its subtypes. When you initialize your state, it should look something like this:
getInitialState() {
return { absoluteChangeX: new Animated.Value(0) };
}
The fact that the type declaration in the framework method is any is just a lack of constraint, not an explicit invitation to pass any value into it.
See the Animated docs for more examples.
I run into this issue sometimes (React hooks instead) when I forget to set my variable to the .current of the ref:
function MyComponent() {
const animatedValue = useRef(new Animated.Value(0.0)).current; // Notice the .current
}
This may not necessarily answer the original question, but developers who encounter this error while using React hooks may end up here so maybe it will help someone.
I ran into this issue because I used the animated value (2) instead of the object (1):
const animatedValue = useRef(new Animated.Value(0.0)).current; // (1)
const transform = animatedValue.interpolate({
inputRange: [0.0, 1.0],
outputRange: [0, 100]
}); // (2)
Animated.timing(animatedValue, { // USE animatedValue, NOT transform HERE!
toValue: 1.0,
duration: 3000,
});
Hope this can help anyone that was new to React Native Animation (like me :) )...

Vuejs deep nested computed properties

I'm not really understanding where to put function() { return {} } and where not to when it comes to deeply nesting computed properties.
By the way, this is in a component!
computed: {
styles: function() {
return {
slider: function() {
return {
height: {
cache: false,
get: function() {
return 'auto';
}
},
width: {
cache: false,
get: function() {
return $('#slideshow').width();
}
}
}
}
}
}
},
This is returning undefined. When I get rid of the function() { return {} } inside of the slider index, it returns an object when I do styles.slider.width instead of the get() return. It just shows an object with cache and get as indexes..
Thanks for any help!
The reason I'm asking is because I have multiple nested components that involve styling from the parent. Slider, tabs, carousels, etc. So I wanted to organize them like this.
I believe you mean to return a computed object, but not actually structure the computation in a nested manner?
What the others have said regarding the 'computed' hook not having syntax for nesting is correct, you will likely need to structure it differently.
This may work for you: I generate many objects in a similar fashion.
computed: {
computedStyles(){
var style = {slider:{}}
style.slider.height = 'auto'
style.slider.width = this.computedSlideshowWidth
return style
},
computedSlideshowWidth(){
return $('#slideshow').width()
}
As per 2020 and Vue 2.6.12 this is completelly possible. I believe this has been possible since v.2 but cannot confirm.
Here is the working example:
this.computed = {
// One level deep nested,
// get these at `iscomplete.experience`
// or `iscomplete.volume`
iscomplete: function() {
return {
experience: this.$data.experience !== null,
volume: this.$data.volume > 100,
// etc like this
};
},
// More levels deep nested.
// Get these at `istemp.value.v1 and `istemp.value.v2`
istemp: function() {
return {
value1: {
v1: this.$data.experience,
v2: 'constant'
}
}
}
};
As a result you will be able to access your deep nested computed in your template as e.g. follows <span v-text="iscomplete.experience"></span> that will output <span>true</span> for the first example computed above.
Note that:
Since Vue v.2 cache key is deprecated;
Vue would not execute functions assigned to a computed object nested keys;
You cannot have computed for non-Vue-reactive things which in your case is e.g. $('#slideshow').width(). This means they are not going to be re-computed on their content change in this case (which is a computed's sole purpose). Hence these should be taken away from computed key.
Other than that I find nested computeds to be quite helpful sometimes to keep things in better order.

Is it possible to use RGBA colors with PlanetaryJS elements?

I'm drawing some points over a planet drawn in planetaryjs, and I'd like to make them semi-transparent using RGBA color.
planet.loadPlugin(function(planet) {
planet.onDraw(function () {
planet.withSavedContext(function (context) {
var verylow = (function () {
var verylow = null;
$.ajax({
'async': false,
'global': false,
'url': 'verylow.json',
'dataType': "json",
'success': function (data) {
verylow = data;
}
});
return verylow;
})();
context.beginPath();
planet.path.context(context)(verylow);
context.fillStyle = 'green';
context.fill();
//context.stroke();
context.closePath();
});
});
});
context.fillStyle will also take hex codes, i.e.
context.fillStyle= '#999999';
but it won't take
context.fillStyle= 'rgba (255, 0, 0, 0.6)';
Is this just a limitation of the way that planetary is designed, or can anyone suggest another way to get any level of transparency?
edit: verylow.json contains a bunch of "Point" objects, FYI.
You need to remove the space after the rgba.

Specify the color for a Pie in Dojo Charting

I am using Dojo 1.9, using memoryStore and the store has 4 data elements, in addition to the key. For each of the 4 data elements, I need to plot a Pie-Chart. working fine but only issue is that I do not know how to specify the color.
The identifier could be one of the Following - Low, Moderate,High and Extreme.
I want to use the same colors for each identifier, in all the charts. Is it possible for me to specify a color based on the value of the identifier?
The code snippet is as shown below:
var store = new Observable(new Memory({
data: {
identifier: "accumulation",
items: theData
}
}));
theChart.setTheme(PrimaryColors)
.addPlot("default", {
type: Pie,
font: "normal normal 11pt Tahoma",
fontColor: "black",
labelOffset: -30,
radius: 80
}).addSeries("accumulation", new StoreSeries(store, { query: { } }, dataElement));
I'm possibly misunderstanding your question here (is the plot interacting directly with the store? StoreSeries?), but is the fill property what you're looking for?
// Assuming data is an array of rows retrieved from the store
for(var i etc...) {
// make chart
// ...
chart.addSeries("things", [
{ y: data[i]["low"], fill: "#55FF55", text: "Low" },
{ y: data[i]["mod"], fill: "#FFFF00", text: "Moderate" },
{ y: data[i]["high"], fill: "#FFAA00", text: "High" },
{ y: data[i]["extr"], fill: "#FF2200", text: "Extreme" }
]);
}
Update: When using a StoreSeries, the third argument (dataElement in your code) can also be a function. You can use the function to return an object (containing the properties above, such as fill) instead of just a value.
chart.addSeries("thingsFromStore", new StoreSeries(store, {}, function(i) {
return {
y : i[dataElement],
text: "Label for " + i.accumulation,
fill: getColorForAccumulation(i)
};
}));