Home > OS >  How to match a string if it ends differently?
How to match a string if it ends differently?

Time:01-25

I have a list of navlinks. When I'm on a certain page, that navlink should be highlighted. I also want the page up (only) one level to have its navlink highlighted as well, so:

All pages: /blogs, blogs/careers, blogs/authors

Page: /blogs/author Highlight: /blogs/author, /blogs

Page: /blogs/author/Lauren-Stephenson Highlight: /blogs/author/Lauren-Stephenson, blogs/authors Here's how I'm doing it:

import React from 'react';

const navlinks = ["/blogs", "blogs/careers", "blogs/authors"]
const currentPath = "/blogs/authors/Lauren-Stephenson"

export function App(props) {
  return (
    <div className='App'>
     {navlinks.map((links) => 
       <div style={{color: currentPath.includes(links) ? 'green' : 'white'}}>{links}</div>
     )}
    </div>
  );
}

But my code not only highlights /blogs/Authors/, it also highlights /blogs, which is incorrect, because I only want the page up one level to be highlighted.

How can I do this?

currentPage: /blogs/Authors/Lauren-Steph

/blogs (HIGHLIGHTED) INCORRECTLY HIGHLIGHTED!
/blogs/careers
/blogs/authors (HIGHLIGHTED) Correct
currentPage: /blogs/Authors

/blogs 
/blogs/careers
/blogs/authors (Correct)
currentPage: /blogs

/blogs  (Correct)
/blogs/careers
/blogs/authors

CodePudding user response:

You got it the other way around. It's called: Array.protoype.includes() - Notice the "Array". Therefore use an Array:

links.includes(currentPath)

But... given your currentPath is somewhat a longer path string, you might want additionally check for if some of the navlinks startsWith a specific String:

const navlinks = ["/blogs", "/blogs/careers", "/blogs/authors"];

const checkNavPath = (path) => navlinks.some(nav => path.startsWith(nav));

console.log(checkNavPath("/blogs"));
console.log(checkNavPath("/blogs/authors"));
console.log(checkNavPath("/blogs/authors/Lauren-Stephenson"));
console.log(checkNavPath("/recipes/food/mashed-potato"));

Also, make sure your paths start all with /

CodePudding user response:

The easiest way is to check if the path starts with the link and the link only has one extra "/".

Since you don't have proper data (not all of the links/paths start with "/") I had to write a function to normalize them.

const navlinks = ["/blogs", "blogs/careers", "blogs/authors"];

const normalizePath = (path) => path.replace(/^(?!\/)/, "/"); // add the starting "/" if it isn't there

const shouldHighlightLink = (currentPath, link) => {
  currentPath = normalizePath(currentPath);
  link = normalizePath(link);

  return currentPath === link ||
    (currentPath.startsWith(link   "/") &&
      currentPath.split("/").length - 1 === link.split("/").length);
}

console.log(
  "/blogs/authors/Lauren-Stephenson",
  navlinks.reduce((acc, cur) => (
    acc[normalizePath(cur)] = shouldHighlightLink("/blogs/authors/Lauren-Stephenson",
    cur
  ), acc), {})
);

console.log(
  "/blogs/authors",
  navlinks.reduce((acc, cur) => (
    acc[normalizePath(cur)] = shouldHighlightLink("/blogs/authors",
    cur
  ), acc), {})
);

CodePudding user response:

So your highlighting logic seems to be: highlight:

  • current page
  • page one level above

Provided that link formats are consistent using absolute path, you can explicitly check against the 2 paths that should match instead of using string .includes()

const navLinks = ['/blog', '/blog/parent', '/blog/parent/child', '/blog/parent/child/grandchild', '/blog/parent/sibling', '/blog/other', '/blog/other/subpage']

const currentPath = '/blog/parent/child/grandchild'

const getHighlightedPaths = (currentPath) => {
  return [
    currentPath,
    currentPath.substring(0, currentPath.lastIndexOf('/'))
  ]
}

const highlightedPaths = getHighlightedPaths(currentPath)

console.log('1. ', highlightedPaths)

console.log('2. Should highlight paths?', navLinks.map(link => link   ' - '   (highlightedPaths.includes(link) ? 'yes' : 'no')))

Console output:

1.  [
  "/blog/parent/child/grandchild",
  "/blog/parent/child"
]
2. Should highlight paths? [
  "/blog - no",
  "/blog/parent - no",
  "/blog/parent/child - yes",
  "/blog/parent/child/grandchild - yes",
  "/blog/parent/sibling - no",
  "/blog/other - no",
  "/blog/other/subpage - no"
]
  • Related