this inside an async object method [duplicate] - javascript

This question already has answers here:
Methods in ES6 objects: using arrow functions
(6 answers)
Closed 5 years ago.
I creating an object that uses async function methods with babel-polyfill/babel-preset-es2017, however I am having a problem with this:
let obj = () => {
return {
doAsync: async () => {
let thing = await longProcess()
return this.transform(thing)
},
transform: (thing) => {
return psuedoCodeTransform(thing)
}
}
}
let instance = obj()
instance.doAsync()
// TypeError: cannot read property 'transform' of undefined`.
Is this something described in ES2017, a babel-polyfill/regeneratorRuntime gotcha?

Arrow functions do not create their own context. They don't have their own this and this will refer to the enclosing scope's context. In this case (no pun intended), this does not refer to the same object as instance at all.
If you log this inside doAsync, you'll notice it's the window global.

Joseph the Dreamer's response is exactly right obviously, but since I work best by example, here is your code changed which should make it work. Notice the only change is actually defining doAsync as a normal function instead of arrow function:
let obj = () => {
return {
doAsync: async function() {
let thing = await longProcess()
return this.transform(thing)
},
transform: (thing) => {
return psuedoCodeTransform(thing)
}
}
}
let instance = obj()
instance.doAsync()
// TypeError: cannot read property 'transform' of undefined`.

Related

How to call an arrow function that hasn't still be declarated [duplicate]

This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 2 years ago.
I have this in my code:
const [dimensions, setDimensions] = useState(getDimensions())
const getDimensions = () => {
// stuff
}
The function hasn't be declarated when I call it, so I get an error. But, if I declare it as a traditional function no error is going on.
const [dimensions, setDimensions] = useState(getDimensions())
function getDimensions() {
// stuff
}
Is there any way to do this with an arrow function?
This is because with the arrow function example you are declaring a function expression. Function expressions are not hoisted. If you need to use an arrow function, you would need to declare it before use.
I can't speak to why arrow and traditional functions behave differently.
But if you wanted to use an arrow function then you can update your code to set an initial state and only call getDimensions once component is mounted with useEffect.
Example:
const [dimensions, setDimensions] = useState({})
const getDimensions = () => {
// stuff
}
useEffect(()=> {
getDimensions()
}, [])

ES6 Function declaration difficulty [duplicate]

This question already has answers here:
Curly Brackets in Arrow Functions
(3 answers)
What does the arrow function with a () after means? [duplicate]
(3 answers)
Closed 4 years ago.
I am taking a course on React Native and realize that the instructor declares functions in two different ways, for seemingly no different reasons. Please explain when each function declaration should be used:
example = () => ();
vs
example = () => {};
Thank you
Arrow functions can differ in function bodies (Thanks Robbie). The concise function body can only consist of a single expression which is evaluated and implicitly returned. The conventional block function body requires the return keyword or it will return void.
example1 = () => 1 + 1;
example2 = () => {
const result = 1 + 1;
return result;
};
example3 = () => {
const result = 1 + 1;
};
example1() has a concise body and will implicitly return the result of the expression 2.
example2() has a block body and does explicitly return 2.
example3() has a block body and no explicit return, therefore it returns void.
Note that the normal braces () around a concise function body are required if you want to return an object literal:
example = () => ({some: 'object'});

Recursion in Javascript ES6 class [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
I am trying to call the same method within a method in a Javascript ES6 class but it is not working.
class Client {
constructor(connection) {
this.channels = [];
this.nickname = null;
this.user = null;
this.realName = null;
connection.on('data', this.parse_message);
}
parse_message(message) {
let messageObject = {};
if (message.includes('\r\n')) {
message = message.split('\r\n');
message.forEach((el) => {
this.parse_message(el);
});
}
else {
message = message.split(' ');
console.log('Message Received: ', JSON.stringify(message));
}
}
}
When ran I get this error TypeError: this.parse_message is not a function. I tried assigning this to a variable self at the top but that still didn't work.
Pass an arrow function as the bound handler so that you can keep this associated with the method.
connection.on('data', (...args) => this.parse_message(...args));
Now your this in the forEach callback will be the expected value.
You can use bind in the constructor:
this.parse_message = this.parse_message.bind(this);
Bind-ref:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Why can't I access `this` within an arrow function? [duplicate]

This question already has answers here:
What does "this" refer to in arrow functions in ES6?
(10 answers)
Closed 7 years ago.
This code below should work as expected, and log "meow", here an example.
function Cat () {
this.animalNoise = 'meow'
}
Cat.prototype.sound = () => {
console.log(this.animalNoise)
}
let cat = new Cat()
cat.sound()
It doesn't work, this error appears TypeError: Cannot read property 'animalNoise' of undefined and when you convert the arrow function to an actual function declaration it works. It seems like with the arrow function, I no longer have access to this. What's going on here?
To be clear, the above code does not work where the following does, and I'm very curious why.
function Cat () {
this.animalNoise = 'meow'
}
Cat.prototype.sound = function() {
console.log(this.animalNoise)
}
let cat = new Cat()
cat.sound()
Arrow functions perform lexical binding and uses the surrounding scope as the scope of this. For example, imagine (for some weird reason) you define Cat inside of a Dog constructor.
function Dog() {
// do dog like things
function Cat() { ... }
Cat.prototype.sound = () => {
// this == instance of Dog!
};
}
So whatever the surrounding scope is becomes the scope of an arrow function.

Is it possible to use => to define objects? [duplicate]

This question already has answers here:
What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind?
(3 answers)
Closed 7 years ago.
I'm trying to use the arrow-constructor to create an object:
var Countable = (data) => {
return data;
}
But when creating an object:
new Countable(newSubscriptions)
I get the error
Uncaught TypeError: (data) => {
return data;
} is not a constructor
I get the expected output by doing
var Countable = function(data) {
return data;
}
Yes, you can use an arrow function to create new objects:
var Countable = () => {
return {}; // This function returns a new object
};
var o = Countable();
However, you can't instantiate an arrow function, because it doesn't have the [[Construct]] internal method. So using new will throw.

Categories

Resources