Nesting Template Literals: A Recommended Approach
Tags: todayilearned, react, javascript, webdev
Published: 2021-03-18 15:59:46

Code quality is essential, as it impacts the overall software quality. In consequence, software quality affects the safety, security, and reliability of any codebase.

### The backstory 🔙
For a few months now, I'm using [SonarCloud](https://sonarcloud.io/) on my GitHub repositories to monitor code quality. I find it a valuable tool for checking my code and keeping me updated on any corrections needed. Additionally, I've also learned a great deal about coding practices that I would typically neglect.

One of the "code smells" picked up was the nesting of Template Literals. SonarCloud gave me a big fat notice saying **Template literals should not be nested**

### My Problem 🤔
This issue resulted from my attempt to add breakpoints to my [styled-components](https://styled-components.com/) on a project. The problem turned out to be a good learning moment. Thus, here is me sharing the lesson with you to hopefully not repeat my mistakes. 

Nesting together multiple template literals can create unnecessary complexity, which reduces the code quality. The code becomes less readable and can cause maintainability issues overtime. 

---

Consider this example:
```javascript 
let color = "red";
let count = 3;
let message = `I have ${color ? `${count} ${color}` : count} apples`; // Noncompliant; nested template strings not easy to read
```
A better practice, in these situations, is to <u>_move the nested template into a separate statement_</u>.
```javascript
let color = "red";
let count = 3;
let apples = color ? `${count} ${color}` : count;
let message = `I have ${apples} apples`;
```

---

Here is the initial setup of my styled-components file. It is the hero section of an application. Within the styled section, `respondToDeviceWidth` creates a nested template literal with CSS values. 

```javascript
// HeroStyles.js

import styled from 'styled-components';
import respondToDeviceWidth from '../../utils/mediaQueries';

export const StyledHeroSection = styled.section`
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: linear-gradient(
    145deg,
    rgba(253, 38, 71, 1) 0%,
    rgba(252, 128, 45, 1) 75%,
    rgba(250, 167, 43, 1) 100%
  );

  ${respondToDeviceWidth.sm`
    margin-bottom: 2em;
  `}
`;
```

`respondToDeviceWidth` utilizes styled-components `css` prop to create the required media query depending on the chosen `breakpointsData`. 

```javascript
// utils/mediaQueries/index.js

import { css } from 'styled-components';
import breakpointsData from '../../data/breakpointsData';

const respondToDeviceWidth = Object.keys(breakpointsData).reduce(
  (acc, label) => {
    acc[label] = (...args) => css`
      @media (min-width: ${breakpointsData[label]}) {
        ${css(...args)};
      }
    `;
    return acc;
  },
  {}
);

export default respondToDeviceWidth;
```

`breakpointsData` is an object which holds some standard device widths.

```javascript
// data/breakPointsData.js
const breakpointsData = {
  xs: '480px',
  sm: '768px',
  md: '992px',
  lg: '1200px',
};

export default breakpointsData;
```

### The Solution 💡
The main issue pointed out by SonarCloud to me was the nesting of the template literals in my styled hero component. To fix this, all I needed to extract the `respondToDevice` width into a separate statement.

```javascript
// HeroStyles.js

import styled from 'styled-components';
import respondToDeviceWidth from '../../utils/mediaQueries';

const smStyles = respondToDeviceWidth.sm`
margin-bottom: 2em;
`;

export const StyledHeroSection = styled.section`
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: linear-gradient(
    145deg,
    rgba(253, 38, 71, 1) 0%,
    rgba(252, 128, 45, 1) 75%,
    rgba(250, 167, 43, 1) 100%
  );

  ${smStyles}
`;

```


### Conclusion 🏁
That's pretty much it. I learned a better method for nesting template literals. A method that reduces the complexity of my codebase. Thanks to SonarCloud, I was to improve my code quality (by a small significance atleast). 

Now are SonarCloud recommendations and practices the only ones that set in stone? Most likely not! As far as code analyzers go, I'm sure there are a plethora of choices.

Let me know more about them in the comments below ✌️

---
Full repo 👉 [here](https://github.com/reMRKableDev/ds-talks) 👈