DEV Community

Orkhan Jafarov
Orkhan Jafarov

Posted on • Updated on

πŸ¦Έβ€β™‚οΈ 11 JavaScript Tips and Tricks to Code Like A Superhero (Vol.2)

Hi JS-heroes! Finally done with this new article! Let's go ahead ✨

1. Generate a list with random numbers

We need A LOT of fake data, for different reasons. So here's a way to do that gently.

Array.from({ length: 1000 }, Math.random)
// [ 0.6163093133259432,β€ˆ0.8877401276499153,β€ˆ0.4094354756035987,β€ˆ...] - 1000 items
Enter fullscreen mode Exit fullscreen mode

2. Generate a list with numbers

Yep, just one more trick to generate a list with numbers.

Array.from({ length: 1000 }, (v, i) => i)
// [0, 1, 2, 3, 4, 5, 6....999]
Enter fullscreen mode Exit fullscreen mode

1-2 edited. Thanks to Andrew Courtice

3. Convert RGB β†’ HEX

Convert your RGB to HEX without any libs!

const rgb2hex = ([r, g, b]) =>
  '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).substr(1);

rgb2hex([76, 11, 181]);
// #4c0bb5
Enter fullscreen mode Exit fullscreen mode

4. Convert HEX β†’ RGB

What's about convert it back?! Here's a nice way to implement that.

const hex2rgb = hex =>
  [1, 3, 5].map((h) => parseInt(hex.substring(h, h + 2), 16));

hex2rgb("#4c0bb5");
// [76, 11, 181]
Enter fullscreen mode Exit fullscreen mode

5. Odd or Even

Another yet odd/even checking.

const value = 232;  

if (value & 1) console.log("odd");
else console.log("even");
// even
Enter fullscreen mode Exit fullscreen mode

6. Check valid URL

I guess most of you use this way to validate URL, but anyway. Let's share it

const isValidURL = (url) => {
  try {
    new URL(url);
    return true;
  } catch (error) {
    return false;
  }
};

isValidURL("https://dev.to");
// true

isValidURL("https//invalidto");
// false
Enter fullscreen mode Exit fullscreen mode

7. N something ago

Sometimes you need something to print a date to 6 minute(s) ago, but don't want to import monster-size libs. Here's a small snippet that does it, easily modify it as you wish and go ahead.

const fromAgo = (date) => {
  const ms = Date.now() - date.getTime();
  const seconds = Math.round(ms / 1000);
  const minutes = Math.round(ms / 60000);
  const hours = Math.round(ms / 3600000);
  const days = Math.round(ms / 86400000);
  const months = Math.round(ms / 2592000000);
  const years = Math.round(ms / 31104000000);

  switch (true) {
    case seconds < 60:
      return `${seconds} second(s) ago"`;
    case minutes < 60:
      return `${minutes} minute(s) ago"`;
    case hours < 24:
      return `${hours} hour(s) ago"`;
    case days < 30:
      return `${days} day(s) ago`;
    case months < 12:
      return `${months} month(s) ago`;
    default:
      return `${years} year(s) ago`;
  }
};

const createdAt = new Date(2021, 0, 5);
fromAgo(createdAt); // 14 day(s) ago;
Enter fullscreen mode Exit fullscreen mode

8. Generate path with params

We work a lot with routes/paths and we always need to manipulate them. When we need to generate a path w/ params to push browser there, generatePath helps us!

const generatePath = (path, obj) =>
    path.replace(/(\:[a-z]+)/g, (v) => obj[v.substr(1)]);

const route = "/app/:page/:id";
generatePath(route, {
  page: "products",
  id: 85,
});
// /app/products/123
Enter fullscreen mode Exit fullscreen mode

9. Get params from path

Yes! Now we need to get our params back. Also, you can pass serializer to parse your data gently.

const getPathParams = (path, pathMap, serializer) => {
  path = path.split("/");
  pathMap = pathMap.split("/");
  return pathMap.reduce((acc, crr, i) => {
    if (crr[0] === ":") {
      const param = crr.substr(1);
      acc[param] = serializer && serializer[param]
        ? serializer[param](path[i])
        : path[i];
    }
    return acc;
  }, {});
};

getPathParams("/app/products/123", "/app/:page/:id");
// { page: 'products', id: '123' }

getPathParams("/items/2/id/8583212", "/items/:category/id/:id", {
  category: v => ['Car', 'Mobile', 'Home'][v],
  id: v => +v
});
// { category: 'Home', id: 8583212 }
Enter fullscreen mode Exit fullscreen mode

10. Generate path with query string

Of course, we work with paths and we need to generate path with query too.

const generatePathQuery = (path, obj) =>
  path +
  Object.entries(obj)
    .reduce((total, [k, v]) => (total += `${k}=${encodeURIComponent(v)}&`), "?")
    .slice(0, -1);

generatePathQuery("/user", { name: "Orkhan", age: 30 }); 
// "/user?name=Orkhan&age=30"
Enter fullscreen mode Exit fullscreen mode

11. Get params from query string

Now it's a time to get params from query string.

const getQueryParams = url =>
  url.match(/([^?=&]+)(=([^&]*))/g).reduce((total, crr) => {
    const [key, value] = crr.split("=");
    total[key] = value;
    return total;
  }, {});

getQueryParams("/user?name=Orkhan&age=30");
// { name: 'Orkhan', age: '30' }
Enter fullscreen mode Exit fullscreen mode

Conclusion

Try to understand how everything works and keep your code nice/clean.

Take your JS-hero's skills and save the world! βœ¨πŸ¦Έβ€β™‚οΈ ✨

Save and contribute tips/tricks on github code-like

Top comments (21)

Collapse
 
crimsonmed profile image
MΓ©dΓ©ric Burlet

One that I love is this:

const someVar = null
const myValue = someVar || "default text"
Enter fullscreen mode Exit fullscreen mode

The or operator works the same as an elvis operator.

This is useful if you want to display a default value when you can't get data from an api or if some data is null for a key.

This can be chained with objects

const someVar = {foo: {bar: null}}
const myValue = someVar?.foo?.bar || "default text"
Enter fullscreen mode Exit fullscreen mode
Collapse
 
lesleyvdp profile image
Lesley van der Pol • Edited

Love this one too, it's also useful to prevent errors when destructuring something that could be undefined:

const { foo, bar } = couldBeUndefined || {};
Enter fullscreen mode Exit fullscreen mode

This can prevent errors such as "Cannot read foo of undefined".

Collapse
 
lampe profile image
Micha

With ES2021 we have ||= :)
Which makes the syntax even cooler

I made a video about new features here:
youtu.be/hxmFYToenxE

Collapse
 
crimsonmed profile image
MΓ©dΓ©ric Burlet

True but not fully supported yet

Thread Thread
 
lampe profile image
Micha

With the right babelJS version it is ;)

Thread Thread
 
crimsonmed profile image
MΓ©dΓ©ric Burlet

And then you're bringing big pieces of extra code for not much πŸ˜‰ good way to slow websites.

Thread Thread
 
grzesiekgs profile image
Grzesiek Dunin-ŚlΔ™czek

I would say that developer convenience is more than a lot. Also, few bytes of code for polyfill, definitely will not slow down the website.

Thread Thread
 
crimsonmed profile image
MΓ©dΓ©ric Burlet

I tend to think of client first. UX is more important than writing one word less. for a developer. between users having slow internet speeds, limited networks and not the greatest machines bringing one poly-fill here and there vs zero can make a huge difference. If you are making something just for you or limited public then why not but the difference in code between the statement I used vs using ||= is not that big that it would justify using a poly-fill on my end. If we were talking about a promise polyfill for example that would be a different matter.

But in the end everyone codes differently. So whatever suits your coding style then use it.

Collapse
 
andrewcourtice profile image
Andrew Courtice

Great article!

It's worth noting that the first 2 examples can be written ever so slightly shorter using Array.from as the Array.from method supports a mapping function as it's second argument.

Here's the first example using Array.from:

Array.from({ length: 1000 }, Math.random)
Enter fullscreen mode Exit fullscreen mode

And the second example:

Array.from({ length: 1000 }, (v, i) => i)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
orkhanjafarovr profile image
Orkhan Jafarov

You're right! This way is slightly shorter! I'll replace mine with them
Thank you mate!

Collapse
 
ogheneovo12 profile image
ogheneovo12

Here is what I use

[...Array(1000).keys()]
Enter fullscreen mode Exit fullscreen mode
Collapse
 
crimsonmed profile image
MΓ©dΓ©ric Burlet
Collapse
 
renzos profile image
Renzo

In the case of no. 5: I would always chose readability over bitwise trickery, when not absolutely necessary. So instead of bitwise AND, just use modulo;

const value = 232;  

if (value % 2) console.log("odd");
else console.log("even");
// even
Enter fullscreen mode Exit fullscreen mode
Collapse
 
chadgauth profile image
Chad Gauthier

Hey just a small improvement to N something ago example to show/hide plural.

const fromAgo = (date) => {
  const ms = Date.now() - date.getTime();
  const seconds = Math.round(ms / 1000);
  const minutes = Math.round(ms / 60000);
  const hours = Math.round(ms / 3600000);
  const days = Math.round(ms / 86400000);
  const months = Math.round(ms / 2592000000);
  const years = Math.round(ms / 31104000000);
  let ago;

  if(seconds < 60)
    ago = `${seconds} second"`;
  else if (minutes < 60)
    ago = `${minutes} minute`;
  else if (hours < 24)
    ago = `${hours} hour`;
  else if (days < 30)
    ago = `${days} day`;
  else if (months < 12)
    ago = `${months} month`;
  else
    ago = `${years} year`;

  const isSingular = ago.indexOf("1 ") === 0;

  ago += isSingular ? " ago" : "s ago";
  return ago;
}

const createdAt = new Date(2021, 0, 5);
fromAgo(createdAt); // 14 days ago
Enter fullscreen mode Exit fullscreen mode
Collapse
 
fvlasenko profile image
Fedor Vlasenko
const generatePathQuery = (path, obj) =>`${path}?${new URLSearchParams(obj).toString()}`;
const link = generatePathQuery("/user", { name: "Orkhan", age: 30 });
console.log(link);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
reflexgravity profile image
Joel D Souza
case days < 30:
      return `${days} day(s) ago`;

Enter fullscreen mode Exit fullscreen mode

This will not work for months with 31 days.

Collapse
 
orkhanjafarovr profile image
Orkhan Jafarov • Edited

It's a just simple version for that formatter. That's why it shows average time.
But it's okay with 31 days. If it's more than 30 days then 1 month;

example

new Date(2021, 0, 31); // now - 2021-01-30T20:00:00.000Z
const createdAt = new Date(2021, 0, 1); // 2020-12-31T20:00:00.000Z
fromAgo(createdAt); // 1 month(s) ago
Enter fullscreen mode Exit fullscreen mode

You can also replace Date.now() with your own date to check with date.getTime()

Collapse
 
aligulmaliyev profile image
Ali Gulmaliyev

Thanks for your work.

Collapse
 
larsolt profile image
Lars

Array.from() is amazing! I always used new Array(10). Thanks :)

Collapse
 
mantiq profile image
A.Z.

Great article :D

Some comments may only be visible to logged-in visitors. Sign in to view all comments.