Nesting Template Literals: A Recommended Approach
Malcolm R. Kente
Posted on March 18, 2021
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 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 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:
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 move the nested template into a separate statement.
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.
// 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
.
// 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.
// 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.
// 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 👈
Posted on March 18, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.