How do I access a parent object's name in node.js? - javascript

I am trying to write a universal function that can log some useful data in several different objects, but I don't want to have to pass a parameter that is unique to each object. Ideally, the initial name of the object, like LaunchRequestHandler would be a perfectly sufficient bit of data to use. How can I access this object's name?
const LaunchRequestHandler = {
canHandle(handlerInput) {
//I want to be able to know the name of the outer parent here.
//In this case, I would expect to retrieve 'LaunchRequestHandler'
logCanHandle(handlerInput);
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
}

I don't really understand what are you trying to do but maybe you can do something with ES6 classes, like so:
class LaunchRequestHandler {
canHandle() {
console.log(this.constructor.name);
}
};
const x = new LaunchRequestHandler();
x.canHandle(); // outputs 'LaunchRequestHandler'

Related

How destructure an object starting from a constant?

I have a utils/constant.js file with:
// Key of total elements in remote collection
export const TOTAL_ELEMENTS = "totalElements";
I need to access to totalElements via the constant.
import { TOTAL_ELEMENTS } from "./constants.js";
[...]
let data = {
content: "foo",
totalElements: 54
};
if(TOTAL_ELEMENTS in data) {
// pseudocode, of course it doesn't work.
// of course in my case need to return 54
const { TOTAL_ELEMENTS } = data;
return TOTAL_ELEMENTS;
}
Edit:
As #pilchard mentioned, using Object.prototype.hasOwnProperty is a better way of doing this in case the value is falsy:
if (data.hasOwnProperty(TOTAL_ELEMENTS)) {
return data[TOTAL_ELEMENTS]
}
Original answer:
While the answer #jsN00b provided works and is closer to OP's #sineverba code, there's an issue here since the in operator checks for the specified property in both the specified object AND its prototype chain.
This means that, for example, if datas prototype is Object.prototype, something like 'toString' in data would work as well.
For that reason, you could use something like the following to only check for the 'totalElements' key in the object itself, and avoid destructuring:
if (data[TOTAL_ELEMENTS]) {
return data[TOTAL_ELEMENTS]
}
The desired objective is:
use the constant TOTAL_ELEMENTS (& not directly the prop-name)
check if data has the corresponding prop
if found, then return the value of the prop
The below code-sample may be one solution to achieve the desired objective:
if (TOTAL_ELEMENTS in data) return data[TOTAL_ELEMENTS];
NOTE
The above does not de-structure the data. It access the corresponding prop directly without the need to destructure.

Convert var to const javascript

Is it possible to convert a var to a const?
Say in a scenario like this:
var appname = ''
function setAppName(name) {
appname = name // can I convert this to const now?
}
Basically, this is for a parameter level. Parameter needs to be accessible throughout the file and I want to make it const after first assignment. Is this possible?
To add: If there is any other way besides creating an object with to contain this parameter, it would be better (for a more straightforward solution). I will be working on multiple parameters like this and freezing an object will cause the entire object to freeze. I am hoping to do this on the parameter level.
So either change the parameter to become const. OR (this one I dont think is possible) change the scope of the paramter to global:
function setAppName(name) {
const appname = name // can I change the scope and make this global?
}
Thanks.
Put your app name in an object and freeze it.
let appSettings = { name: "" };
function setAppName(name) {
appSettings.name = name;
Object.freeze(appSettings);
}
Freezing prevents adding, removing and modifying the values of the properties in your object so you should call Object.freeze only once after all other settings (if there are more variables you want to make constant) have been set.
You can do this using a object.
const globals = {
appname: ''
}
function setAppName(name) {
globals.appname = name;
Object.freeze(globals)
// After this point, value of appname cannot be modified
}
Thank you for all your inputs.
I was able to find a workaround for what I was trying to achieve.
var appname = ''
function setAppName(name) {
if (appname === '') {
appname = name // can I convert this to const now?
}
}
Although this doesnt convert it to const, I just added a guard on the setter and it will not be able to overwrite the value now (unless otherwise I am going to initialize again to an empty string).
It is not fool-proof, but this will address my need.
Thanks all!

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.

How to get current property function's name - JavaScript

I have an object that looks like below. Basically it contains properties that call a method. What I would like to be able to do is, instead of having DEVELOPER twice (Once for the property name and once for the parameter value), I'd like to get the current property of what was called in order to get this.
Also I don't want to pass in 'DEVELOPER' as a parameter in the initial call because I want intellisense to pick it up.
return {
DEVELOPER: function ()
{
return getEmailRecipients("DEVELOPER")
}
}
//it get's called like this.
emailGroups.DEVELOPER();
Essentially I'd like to do something like
return {
DEVELOPER: function ()
{
return getEmailRecipients({this.currentPropName}) //Which would equal DEVELOPER.
}
}
If there is a better way to do this, I am all ears.
Thanks in advance!
As far as I know, this is not possible, or at least it's not built-in.
You can use the function name as defined in arguments.callee like this...
arguments.callee.name
But the name property of functions is not well supported.
You might try something like this...
this.toSource().match(/\{(.*?):/)[1].trim ()
But that only works for one item in an object, and only the first item.
You might also try defining the object you return as a variable, and loop over that object giving every item a new property that contains the item name.
Like so...
// Object to return to emailGroups
var data = {
DEVELOPER: function ()
{
return getEmailRecipients (arguments.callee.givenName)
}
}
// Give each object item a new property containing the name
for (var name in data) {
if (data.hasOwnProperty (name) === true) {
data[name].givenName = name;
}
}
// Return data variable as emailGroups
return data;

Storing an ES6 Javascript class's getter/setter when inheritance is involed

Edit: The reason I am doing the below process is so I can store the reference to the getter/setter in a dictionary. This allows me to have the key of my dictionary be an ID of an HTML element. Thus, if a property is changed in the HTML, I can do something like:
var propData = allMyGetterSetters[e.originalTarget.id];
propData.getSet.set(propData.obj, e.originalTarget.value);
This also allows me to do a loop and update all the HTML, should my logic change it.
I need to store a reference to the getter/setters of a few properties of one of classes. I've managed to do this with the following code:
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(myClassObj.position), "x");
For simplicity, since I have to do this several times, I have the following method:
_makeGetSetObj(object, property){
return {
getSet: Object.getOwnPropertyDescriptor(Object.getPrototypeOf(object), property),
obj: object
};
}
And subsequent code would look something like this:
var xPos = this._makeGetSetObj(myClassObj.position, "x");
// ...
xPos.getSet.get(xPos.obj);
All of this works perfectly.
However, I now need to store a reference to a getter/setter of my myclassObj object. However, the following does not work
this._makeGetSetObj(myClassObj, "name");
This actually gives me an error that name does not exist on the object. I've managed to figure out that the problem is my inheritance, which looks something like this
|-- BaseClass
|-- MyClass
|-- DerivedClass
The problem seems to be that myClassObj is actually an object of type DerivedClass, which doesn't have the property name on it.
So, if I do this:
this._makeGetSetObj(myClassObj.__proto__, "name");
It works to get the prototype, but when I try to use it as shown above (with my xPos example), it fails because it seems to still be storing an reference in obj as a DerivedClass object.
If I pull outside of my method, and try things manually, this works:
var name = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(myClassObj.__proto__), "name");
name.get(myClassObj);
This obviously breaks my method though, as one part requires the __proto__ while the other part does not.
So, my question is: Is there a way to keep my current logic, or will I have to create a special method for the places with the described problem?
Thanks.
Hardcoded prototype doesn't smell good. Prototype chains should always be iterated:
let proto = obj;
let descriptor;
do {
descriptor = Object.getOwnPropertyDescriptor(proto, prop);
} while (!descriptor && proto = Object.getPrototypeOf(proto))
...
This functionality has been already implemented by Reflect. Instead of parsing descriptors manually, it may be
const getSet = {
get: () => Reflect.get(obj, prop),
set: (val) => { Reflect.set(obj, prop, val) }
};
Or... just
const getSet = {
get: () => obj[prop],
set: (val) => { obj[prop] = val }
};
Because this is what happens when accessors are called directly.

Categories