Reputation: 45360
Is it possible in ES6 to set a variable inside of a try{}
using const
in strict mode?
'use strict';
const path = require('path');
try {
const configPath = path.resolve(process.cwd(), config);
} catch(error) {
//.....
}
console.log(configPath);
This fails to lint because configPath
is defined out of scope. The only way this seems to work is by doing:
'use strict';
const path = require('path');
let configPath;
try {
configPath = path.resolve(process.cwd(), config);
} catch(error) {
//.....
}
console.log(configPath);
Basically, is there any way to use const
instead of let
for this case?
Upvotes: 69
Views: 39548
Reputation: 21
Use IIFE
const parsedJSON = (() => {
try {
return JSON.parse(badJSON);
} catch (error) {
return {};
}
})();
Upvotes: 2
Reputation: 11
You can just do:
const result = await promise.catch(err=>{
console.log(err)
})
Upvotes: 1
Reputation: 636
You can avoid the try block altogether if the function is async! Just learned this today, thought I'd share!
More broadly applicable to just your situation as this is the top Google result for "const in a try block"
'use strict';
const path = require('path');
const getPath = async () => {
return path.resolve(process.cwd())
}
const logPath = async () => {
const configPath = await getPath().catch(e => console.log(e)) <--avoid the try
console.log(configPath);
}
logPath()
Works great when you're already in an async function and need to wait for something else:
async function main() {
const result = await asyncTask().catch(error => console.error(error));
}
Learned from: https://stackoverflow.com/a/55024396/2936521
Upvotes: 3
Reputation: 1690
Besides the let
options I see here, another option may be to use an object, as the reference to the object is constant, but it's properties can be altered, so something like this:
'use strict';
const path = require('path');
const configPath = { value: null };
try {
configPath.value = path.resolve(process.cwd(), config);
} catch(error) {
//.....
}
console.log(configPath.value);
It would probably be cleaner to stick with let, but I just wanted to point out another possible option.
Upvotes: 1
Reputation: 643
There are plenty of good answers here. But it's real annoying to have to manage your lets being inside and out of scope. So if you are like me, and came here searching for a better pattern. I wrote a little utility that helps a ton.
export const tc = <T>(option: { try: () => T; catch: (e: Error) => T }) => {
try {
return option.try()
} catch (e) {
return option.catch(e)
}
}
Here are some unit tests to show how it's useful
import { tc } from './tc'
describe('tc', () => {
it('should return successfully', () => {
const result = tc({
try: () => 1 + 2,
catch: () => -1,
})
expect(result).toEqual(3)
})
it('should catch', () => {
const spy = jest.fn()
const result = tc({
try: (): number => {
throw new Error('Test')
},
catch: (e) => {
spy()
expect(e.message).toEqual('Test')
return -1
},
})
expect(spy).toHaveBeenCalledTimes(1)
expect(result)
})
it('should rethrow', () => {
expect(() =>
tc({
try: (): number => {
throw new Error('Test')
},
catch: (e) => {
throw e
},
}),
).toThrowError()
})
it('should have proper types', () => {
// @ts-expect-error
const result: string = tc({
try: () => 12,
catch: (e) => {
return -1
},
})
})
})
Upvotes: 2
Reputation: 2460
'use strict';
const path = require('path');
const configPath = (function() {
try {
return path.resolve(process.cwd(), config);
} catch (error) {
//.....
}
})()
console.log(configPath);
Upvotes: 37
Reputation: 33439
I would try to use a temp variable with let
and assign that to a const
var after the try
/catch
and 'delete' the temp var.
'use strict';
let temp;
try {
temp = path.resolve(process.cwd(), config);
} catch (error) {
//.....
}
const configPath = temp;
temp = undefined;
console.log(configPath);
Upvotes: 4
Reputation: 35491
Declaring a variable as const
requires you to immediately point it to a value and this reference cannot be changed.
Meaning you cannot define it at one place (outside of try
) and assign it a value somewhere else (inside of try
).
const test; // Syntax Error
try {
test = 5;
} catch(err) {}
On the other hand, both creating it and giving it a value within the try
block is fine.
try {
const test = 5; // this is fine
} catch(err) {}
However, const
is block-scoped, like let
, so if you do create it and give it a value within your try
block, it will only exist within that scope.
try {
const test = 5; // this is fine
} catch(err) {}
console.log(test); // test doesn't exist here
Therefore, if you need to access this variable outside of the try
, you must use let
:
let configPath;
try {
configPath = path.resolve(process.cwd(), config);
} catch(error) {
//.....
}
console.log(configPath);
Alternatively, although probably more confusingly, you can use var
to create a variable within the try
and use it outside of it because var
is scoped within the function, not the block (and gets hoisted):
try {
var configPath = path.resolve(process.cwd(), config);
} catch(error) {
//.....
}
console.log(configPath);
Upvotes: 104
Reputation: 833
Use let
. You cannot use const
. const
does not allow you to reassign the declared constant. While it is generally good practice to declare objects like yours with const
, the entire point of doing so is to allow objects to be mutated without allowing them to be reassigned. You are reassigning the object (thus, defeating the purpose of const
), so use let
instead.
let path = require('path');
// Good to go!
Upvotes: -3