How to match a template string in switch statement with js? - javascript

I have a function that returns a component that depends on the pathname of the window.
getComponentByPathname = (pathname) => {
switch(patname){
case "/view1": return <ViewOneComponent>;
case "/view2": return <ViewTwoComponent>;
}
But the problem starts when I try to evaluate a template string that has one id
getComponentByPathname = (pathname) => {
switch(pathname){
case "/view1": return <ViewOneComponent>;
case "/view2": return <ViewTwoComponent>;
case `/view3/${getId()}`: return <ViewThreeComponent>;
}
It's only working with the first two cases. Why?
Also, I make another attempt. In this case, I literally paste the string with the Id in the third case, like this:
case "view3/1234567": return <ViewThreeComponent>;
And works. But the problem is that I can not hardcode the id in the string.
How I can evaluate that?

My guess would be that getId() is returning a different value then what you expect. I would try the following and make that getId() is returning the expected value when it is being calculated
getComponentByPathname = pathname => {
const case3 = `/view3/${getId()}`;
console.log(`case3 = ${case3}`);
console.log(`pathname = ${pathname}`);
switch (pathname) {
case '/view1':
return <ViewOneComponent>;
case '/view2':
return <ViewTwoComponent>;
case case3:
return <ViewThreeComponent>;
}
};
But if you only need to decide which component to render based on your path then something like this might be more appropriate
const examplePaths = ['view1/', 'view2/', 'view3/', 'view3/1241232', 'view3/8721873216', 'view4/', 'vi/ew1', ''];
const mapper = {
view1: 'ViewOneComponent',
view2: 'ViewTwoComponent',
view3: 'ViewThreeComponent'
};
examplePaths.forEach(ent => {
const splitPaths = ent.split('/');
const mapped = mapper[splitPaths[0]];
if (mapped) {
console.log(mapped);
} else {
console.log('Path not supported');
}
});

Works fine here
function getId() {
return 1234567
}
function test(pathname) {
switch (pathname) {
case '/view1':
return 'ViewOneComponent'
case '/view2':
return 'ViewTwoComponent'
case `/view3/${getId()}`:
return 'ViewThreeComponent'
default:
return 'fail'
}
}
console.log(test('/view3/1234567'))

Related

traverse array of objects and show image according to a type

I have an array of objects in a state in pinia, I get this array in my component. I am trying to show an image or others according to a value that is in the object, I make a function where I go through the array here and using switch I check the type, and return the image that corresponds to the type, I do this but I only get returns the first image if I use a for, if I do it with forEach it returns null, I try to save the value in the function because it is the one that I command to call to show the image, how can I do this so that according to a type I show a different image?
Function where you tried to get the images
const imgSelect = () => {
for(let i = 0; i < obj.value.length; i++){
switch(obj.value[i].type){
case 'one':
return new URL('../assets/images/image1.png', import.meta.url).href
break;
case 'two':
return new URL('../assets/images/image2.png', import.meta.url).href
break;
case 'three':
return new URL('../assets/images/image3.png', import.meta.url).href
break;
default:
return null
break;
}
}
}
here I try to use the image, it is to show it on a map as a markup and show one image or another depending on the type
const imageMarker = imgSelect
As commented
You will have to use Array.map
You are only getting 1 image because you are using a return in for loop. So you return on 1st iteration and remaining iterations never gets evaluated
Sample:
const getUrl = (type) => {
switch (type) {
case 'one':
return new URL('../assets/images/image1.png',
import.meta.url).href
break;
case 'two':
return new URL('../assets/images/image2.png',
import.meta.url).href
break;
case 'three':
return new URL('../assets/images/image3.png',
import.meta.url).href
break;
default:
return null
break;
}
}
const imgSelect = () => {
obj.value = obj.value.map(
(item) => ({...item, url: getUrl(item.type)})
)
}
If you have predefined list of images based on type, you can even create a predefined map and fetch from that. No need to create for every iteration.
const URL_TYPE_MAP = {
one: new URL('../assets/images/image1.png', import.meta.url).href,
two: new URL('../assets/images/image2.png', import.meta.url).href,
three: new URL('../assets/images/image3.png', import.meta.url).href,
}
const getUrl = (type) => {
return URL_TYPE_MAP[type]
}

javascript retrieve value from a map

I am trying to develop a google script app.
Here is one function to create an array map.
function getOffices(){
var result=AdminDirectory.Groups.list({domain:"example.com"})
result=result.groups.filter(function(group){
var str=group.email;
return str.search("-office#example.com")>=0;
})
result=result.map(function(group){ return {name:group.name,email:group.email}})
return result;
}
I have created a logic piece, that I want to execute certain actions based on the results, that looks like this:
var getOrgUnitPath = (accountOffice, accountType) => {
if (accountType === 'facilitator') {
return 'Limited Accounts/Gmail Plus Calendar';
} else {
switch (accountOffice) {
case accountOffice.includes('Boston'):
return "/Standard-Access/Boston";
break;
case accountOffice.includes('New York'):
return '/Standard-Access/New York';
break;
case accountOffice.includes('Lincoln'):
return '/Standard-Access/Lincoln';
break;
default:
return '/Standard-Access';
break;
}
}
};
Lastly, I try to set the organizational unit -- which is ultimately what i am trying to do, but can't seem to get the syntax right, I have tried everything I can think of. I have hardcoded the "accountType" and it worked, so I know the formObject.accountType is functioning properly.
orgUnitPath: getOrgUnitPath(accountType, formObject.accountType),
Thanks in advance!
This is a wrong usage of switch case.
if accountOffice's would be just New York, Boston, Lincoln. Remove the complex condition and replace with
switch (accountOffice) {
case "Boston":
return "/Standard-Access/Boston";
break;
case "New York":
return "/Standard-Access/New York";
break;
case "Lincoln":
return "/Standard-Access/Lincoln";
break;
default:
return "/Standard-Access";
break;
}
If not, use if-else if you have complex condition to check rather than simple match cases
if (accountOffice.includes("Boston")) {
return "/Standard-Access/Boston";
} else if (accountOffice.includes("New York")) {
return "/Standard-Access/New York";
} else if (accountOffice.includes("Lincoln")) {
return "/Standard-Access/Lincoln";
} else {
return "/Standard-Access";
}
I rewrote the code so I could get a better understanding of it. From what I can tell, getOffices lists all offices and getOrgUnitPath returns a path including the first office that matches the ordered list of offices ['Boston', 'NY', 'Lincoln']. If that's the case, what's missing is that the first argument to getOrgUnitPath should be getOffices(), right? (Notice it is the execution of the function getOffices.)
Here's the code "simplified" to my liking. I hope it helps:
const getOffices = () => {
const bigList = x.y.list({ domain: 'example.com' }) // ?
return bigList
.filter(cur => ~cur.email.search('abc'))
.map(cur => ({
name: cur.name,
email: cur.email
}))
}
const getPath = (accOffice, accType) => {
if (accType === 'xyz')
return 'foobar'
const city = ['Boston', 'NY', 'Lincoln']
.find(cur => accOffice.includes(cur))
return `yadayada/${city}`
}
const theFinalObj = {
orgUnitPath: getPath(getOffices(), 'rightHardcodedType')
}

Transform my if conditional to switch case with regex option: javascript

I would like to transfer my if condition to switch case, because then it would look nicer in my code. (I have several switch case).
I can't set the switch parameter to true, because this will break the logic of my code.
if (/(.*)_ERROR/.test(action.type)) {
alert('ok'); //working
}
switch (action.type) {
case /(.*)_ERROR/:
alert('ok'); //not working
break;
...
}
How to write it? The idea is to enter the case only if the word "error" is in the string
Not very ideal but you can use named groups:
const reg = /(?<warning>(.*)_WARNING)|(?<error>(.*)_ERROR)|(?<info>(.*)_INFO)/; // warning, error, or info.
const match = action.type.match(reg);
if (match) {
const groupName = Object.keys(match.groups).find(group => match.groups[group] !== null);
switch (groupName) {
case 'error': // like TEST_ERROR
case 'warning': // like TEST_WARNING
case 'info': // like TEST_INFO
default:
}
}

How to pass multiple values via operator chain to map operator? In NgRx Effect

I am working on Effect, in which I load new data form REST endpoint and then dispatch action to update store with received data. Together with composing searchUrl, there is some computation of newCurrentPage.
How to pass newCurrentPage value along with search request to following operatos?
Code looks like this:
#Effect()
tablePageChanged = this.actions$
.pipe(
ofType(action.tablePageChanged ),
withLatestFrom(this.store.select('tableData')),
switchMap(([action, tableData]) => {
let newCurrentPage: number;
let searchUrl: string;
switch (action.navPage) {
case NavigationPage.First:
newCurrentPage = 1;
searchUrl = tableData.devsTable.firstUrl;
break;
case NavigationPage.Previous:
newCurrentPage = tableData.devsTable.currentPage - 1;
searchUrl = tableData.devsTable.previousUrl;
break;
case NavigationPage.Next:
newCurrentPage = tableData.devsTable.currentPage + 1;
searchUrl = tableData.devsTable.nextUrl;
break;
case NavigationPage.Last:
newCurrentPage = Math.ceil(tableData.devsTable.totalRecords / tableData.devsTable.pageSize);
searchUrl = tableData.devsTable.lastUrl;
break;
default:
break;
}
// HERE: I want to return also 'newCurrentPage', so that I can pass it to 'handleSuccessfulResponse' later
return this.http.get<UserSearchResponse>(searchUrl, {observe: 'response'});
}),
withLatestFrom(this.store.select('tableData')),
map(([response, tableData]) => {
// HERE: I want to get 'newCurrentPage' to pass it to the 'handleSuccessfulResponse' function
return this.handleSuccessfulResponse(response, tableData);
})
);
This RxJS thing is quite new for me, and I haven't quite wrapped my head around it yet, so please be explicit. Thanks!
You can move operators to the closure where this variables were defined, like this:
switchMap(([action, tableData]) => {
// ...
return this.http.get<UserSearchResponse>(searchUrl, {observe: 'response'}).pipe(
// `tableData` and `newCurrentPage` is available here
map(response => this.handleSuccessfulResponse(response, tableData))
);
})
Or use map operator to return pair of [response, newCurrentPage] so it can be used later

const scoping issue within a switch statement

I have the following code in my reducer. In both cases, findFile() returns a result, however, only in the first occurrence (setImageRotation) will "origFile" get set. Changing the name of the second occurrence of "origFile" will allow it to get set. I'm wondering why this is case, as const has a block level scope.
function handler(stateArg, action) {
const state = stateArg || {};
let nextState;
switch (action.type) {
case actions.types.setImageRotation: {
const origFile = findFile(action.fileUid, state.files);
const newfile = Object.assign({}, origFile, { rotation: action.rotation });
nextState = updateStateFile(state, newfile);
break;
}
case actions.types.setImageRegionOfInterest: {
const origFile = findFile(action.fileUid, state.files);
const newfile = Object.assign({}, origFile, { roi: action.roi });
nextState = updateStateFile(state, newfile);
break;
}
}
return nextState || state;
}
Notes:
origFile is not defined anywhere else in my solution.
there are no console errors
Transpiled Code:
case actions.types.setImageRegionOfInterest:{
var origFile = findFile(action.fileUid, state.files);
var newfile = (0, _assign2.default)({}, origFile, { roi: action.roi });
nextState = updateStateFile(state, newfile);
break;
}
case actions.types.setImageRotation:{
var _origFile = findFile(action.fileUid, state.files);
var _newfile = (0, _assign2.default)({}, _origFile, { rotation: action.rotation });
nextState = updateStateFile(state, _newfile);
break;
}
As people stated in the discussion, this code works. What I ran into was a bug with Google Chromes debugger & source mapping. When I turned source mapping off and debugged the transpiled code, I got the correct value for "origfile".

Categories

Resources