Creating an avatar based in the user name with React
Tags: javascript, react, tutorial
Published: 2022-06-20 19:01:34

---
title: Creating an avatar based in the user name with React
published: true
description: Fetching a user avatar field sometimes can come empty from the API we are using. Let's give it some style using their names as avatar.
tags: javascript, react, tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67lg46og28hvpp55h4sy.png
# Use a ratio of 100:42 for best results.
---

We often work with lots of designs about user profiles, and in some situations we need to fetch information about the user and render the avatar stablished, but in some cases it can be an empty string and we need to generate an avatar with the user's first letter of their `first name` and `last name`.

You can see the final result here: [View link](https://codesandbox.io/s/user-card-with-avatar-ox5qe0)

## API & React Hook

We are going to use this [API](https://randomuser.me/api/) to fetch the names and filter the information to just use the names and return 20 results like this:

 `https://randomuser.me/api/?inc=name&results=20`

After this we are going to create a react hook to fetch the information using the fetch API. But first, let's create a folder called `hooks` in the root of the project and a file called `constants` to store the endpoint and keep everything organize. 

```javascript
import { useEffect, useState } from "react";
import { API_ENDPOINT } from "../constants";

export const useData = () => {
  const [userNames, setUserNames] = useState([]);
  useEffect(() => {
    fetch(API_ENDPOINT)
      .then((res) => res.json())
      .then((data) => setUserNames(data.results));
      .catch((error) => console.log(error))
  }, []);
  return {
    userNames
  };
};
``` 
Then, we can go to our `App.js` file and import the hook and render the names.

``` javascript
import { useData } from "./hooks/useData";

export default function App() {
  const { userNames } = useData();
  return (
    <div className="App">
      {userNames.map(({ name }) => (
        <p key={name.first}>{name.first}</p>
      ))}
    </div>
  );
}
```
## Components

We are going to create two components for this project:

- **UserCard**: This will render the card element with the user info and avatar
- **UserPlaceHolder**: this will render the circle with the user's first letters of their `first  name` and `last name`

### User Card component

```javascript
import UserPlaceHolder from "./UserPlaceholder";

const UserCard = ({ first, last }) => {
  let username = `${first} ${last}`;
  return (
    <div className="user">
      <UserPlaceHolder name={username} />
      <p className="user__name">{username}</p>
    </div>
  );
};
export default UserCard;
``` 
### UserPlaceHolder Component
```javascript
import {
  generatePlaceholderName,
  generateRandomColorNumber
} from "../../utils";

const UserPlaceHolder = ({ name }) => {
  const userPlaceholder = generatePlaceholderName(name);
  const placeholderBackground = `hsl(${generateRandomColorNumber()}, 50% , 50%)`;
  return (
    <div
      className="user__placeholder"
      style={{
        backgroundColor: placeholderBackground
      }}
    >
      {userPlaceholder}
    </div>
  );
};
export default UserPlaceHolder;
```
> Note:
> As we are using Plain CSS, the best approach to create a dynamic background color is with the style pro in the element. Other solutions are:
> - Sass
> - CSS in JS (Styled components, emotion)

-------

Notice that in the `UserPlaceHolder` component we are importing two functions from a utils folder that are:

- **generatePlaceholderName**: function that receives user name and returns the first letter of the `first name` and `last name`;
- **generateRandomColorNumber**: function that returns a number between 0 to 360 to use it in the HSL hue property of the style prop. This helps generate a dynamic background for each card;

```javascript
export function generateRandomColorNumber() {
  let randomHue = Math.floor(Math.random() * 360);
  return randomHue;
}
export function generatePlaceholderName(name) {
 //Split name by the space
  let splitUsername = name.split(" "), 

  /* we validate if the data comes correctly with optional chaining. In the worst case, we 
    return a empty string*/

   firstLetter = splitUsername[0]?.[0] ?? "", 
    secondletter = splitUsername[1]?.[0] ?? "";
    return `${firstLetter}${secondletter}`;
}
``` 
## CSS 🧙‍♂️

After explaining the components and functionality, we need some CSS magic

```css
:root {
  --body-bg: #f3f4fa;
  --card-border: #dcdce0;
}

body {
  min-height: 100vh;
  background-color: var(--body-bg);
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
}
.App {
  font-family: sans-serif;
  text-align: center;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 1.5rem;
  justify-content: center;

}
.user {
  border: 1px solid var(--card-border);
  padding: 1rem;
  width: 100%;
  max-width: 180px;
  border-radius: 0.5rem;
  background-color: white;
}
.user__name {
  font-weight: bold;
}
.user__placeholder {
  width: 32px;
  height: 32px;
  margin-left: auto;
  margin-right: auto;
  padding: 0.5rem;
  display: grid;
  color: white;
  place-items: center;
  border-radius: 50%;
}
``` 
## Last Step

 Finally, we import UserCard to render the information and see component in action:

```javascript
export default function App() {
  const { userNames } = useData();
  return (
    <div className="App">
      {userNames.map(({ name }) => (
        <UserCard key={name.first} first={name.first} last={name.last} />
      ))}
    </div>
  );
}
```
## Conclusion

Hope you find it useful for your projects. This is my first article and there are more to come. Happy coding!