Latest Tutorials

Learn about the latest technologies from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

React Carousel: Building the Component from Scratch vs. Using a Library

In this tutorial, I'll show you how to create a simple React carousel from scratch, using hooks, and how to build the component using the React-slick library. When you start a new React project, it's tempting to build your entire UI library from scratch, as you have all the freedom in the world to create the components however you like them and to structure your code in a way that makes sense for the team. Yet, using a library seems like a better option when you need to deliver faster. You can still customize the components and most of the work is already done, so if you're not bothered by the generic look, you can copy-paste the code and you're ready to go. I won't detail all the pros and cons of using libraries, but as a general principle, if you're concerned with the size of your bundle, dislike the bland design of ready-made components, or you anticipate frequent changes in design due to stakeholder requests, for example, it's better to build your own components. So in this tutorial, we'll explore both options: first, we'll build a React carousel from scratch, then we'll create a separate slider component using one of the popular libraries. By the end of this post, you will know how to create a basic React carousel component using hooks, and how to use an out-of-the-box slider component with the React-slick library. As this tutorial doesn't cover the basics of React, to make the most of it, you should already be familiar with: We'll build our component in a React sandbox, so go ahead and create a new project, then add styled components as a dependency.Β  Since we’re building the slider from scratch, we’ll have at least two separate components: one for the slider, and one for the images. So let’s go ahead and create a new folder under src , for the components. Your project structure should look like below. Our main component, the carousel, will be imported in the App.js file, which will look like this: The images will be stored in an array, and passed as props. Next, let's get some images to display in the carousel. I want to use some kitty pictures from Unsplash, but I don't want to store them in a separate folder inside the project. Instead, I want to use the API, so I need the GET endpoint, which looks like this: https://api.unsplash.com/search/photos?query=cats&client_id= To be able to use this endpoint you'll have to create a dev account on Unsplash , so go ahead and do that first. We won't expose the client ID here, so no need to worry about that. Create your dev account here Next, add your client ID to the query to retrieve some kitty images. I'll get 4 images and add the URLs to the ImageData array, as follows: Here I'm using the raw images, but you can get them in different sizes if you prefer. Check the documentation here for more options. So the final App.js file looks like this: Now we can create the image component. Let’s add a new file under components , and call it SlideImage.js .Β I'll use styled components as I find it more convenient. We can start building the final slider component. Let’s create a separate file called Slider.js , and import these two. Β  So let's see what's happening in this component. First, I've added another library for some icons, so that we can add arrows on the sides. The library used here is react-icons , but you can use whatever you prefer, or build your own arrows. Then, I've added some styling in the styles.css file for the arrows, to position them: Now we have the arrows, but we need the slides to move when we click them. So we'll use the useState hook to set the current index of the images, and move to the previous or next slide when the arrows are clicked. I'll explain this part separately. So first we're declaring a new state variable, which is "current" in our case, as we want it to define the index of the current slide. Then, we're defining the functions that will change the state: nextSlide and prevSlide . When the left arrow is clicked, the prevSlide function is called, and what this function does is check the index of the current slide, the subtract one, to display to the previous slide. In the same manner, the nextSlide function checks the index of the current image and adds one, unless the current index is 3, which means that the image is the last one in the carousel. Don't forget that the indexes for the ImageData array start at 0, so the current index 3 actually means that we're referring to the 4th image of the slider, which is the last one. So in this case, the next image to display will be the one with index 0. That's it, you should now have a functional carousel that looks like this: You can see the final code here . For the second part of this tutorial, I’ll use the React-slick library for building the carousel component. Let's go ahead and create a new sandbox, and add react-slick and slick-carousel as dependencies. Your project structure should look like this.Β  To make use of the CSS that this library comes with, you’ll have to import the styles. For this tutorial, I’ll import them directly in the styles.css file:Β  We’ll build the carousel directly in the App.js file, so let’s import from the Slider from the library and start building the component:Β  I've added an empty array for the images that I want to include in the carousel, so we can use the .map method later on and display them one by one. We'll get back to this array in a few minutes, but first, let's solve the styling. Β  As you can see above, there are some classes in the slider, so let's now define them in the styles.css file: Now let's go back to the carousel images. Update the images array as follows: I've downloaded some pictures from Unsplash, and added them in the src folder, in a dedicated images folder. Now I'll import them in the App.js file: And now let's finalize the carousel code: The image URL, alt text, and name are now passed as props. A few words on the settings of the carousel: Dots and infinite are set to true , which just means that the dots are displayed under the carousel, and the images are displayed in an infinite loop. The slidesToShow property determines how many images the user sees in one frame, and the slidesToScroll determines how many images you can scroll at once. The speed property defines the animation speed in milliseconds and the className adds the styling for the slides. If, for example, you want the slider to be displayed vertically instead of horizontally, you can easily do this by adding the vertical property and setting it to true . I'll adjust the styling of the carousel a bit, to center the pictures and titles. Here's the updated code: Your carousel with React-slick should look like this: If you want to display a single picture at once, change the slidesToShow value to 1 instead of 2. Also, to display arrows as we did in the previous carousel, you'll need to do some adjustments to the CSS. So in the styles.css file, adjust the code as follows: Now you'll have a carousel that looks more like the previous one. You can find the project sandbox here . As you can see, the second option - using a library - is much faster and quite straightforward. Thus, if you need to build a React carousel component in a short time and you're not too worried about bundle size or design variations, using the React-slick library is more efficient. You can see a more detailed tutorial on React-slick here , or continue learning React in a more structured manner with the Fullstack React book .

Thumbnail Image of Tutorial React Carousel: Building the Component from Scratch vs. Using a Library

Searching with find and grep

If you work within a disorganized workspace with deeply nested folders and try locating a specific folder, file or code snippet, then your productivity suffers from the constant distraction of manually searching through the workspace. Navigating the workspace and rummaging through every folder (double-clicking each one) to find a single folder or file becomes repetitive and directs attention away from your work. If you forget to close the folders after exploring them, then these opened folders accumulate over time and obstruct subsequent searches by cluttering the screen. Additionally, a computer's file explorer, such as Mac's Finder or Ubuntu's Nautilus, slows down when loading and displaying folders and files within large external hard-drives, thumb drives or SD cards filled (or nearly filled) to maximum capacity. Operating systems based on the UNIX kernel provide the find and grep command-line utilities to search for files/folders and text within a file respectively via pattern matching. With a single-line command, you avoid interacting with the interface of the computer's file explorer. Instead, the command prints the search results to standard output ( stdout ) displayed within the terminal. Both the find and grep commands are considered as some of the most essential building blocks in bash scripting! Knowing how to use them allows you to integrate them into your continuous integration (CI) pipeline to automate search tasks. Below, I'm going to show you: To demonstrate the find and grep commands, we will search for directories and files within a downloaded copy of one of GitHub's most popular repositories, facebook/react . The find command, as its name implies, recursively finds directories and files located within a specified list of directory paths. When a file or directory matches search criteria (based on the options provided to the find command), the find command outputs the matched directories and files by their path relative to the given starting point/s. To recursively list all of the directories and files (including those hidden) within the current directory: To narrow our list down to a specific directory or file, we must provide an expression to the find command: Note : Angle brackets indicate required arguments, whereas square brackets indicate optional arguments. An expression describes how to identify a match via tests , which use certain properties of directories/files to determine which directory/file satisfies the defined conditions: For more information on other tests, check out the find command's documentation in the Linux Manual Page. To get started, let's search for all files named package.json . Note : This command also searches for all directories named package.json . It is highly unlikely for directory names to contain extensions. To limit the search to files only, add the -type f test. If we try to search for directories or files that do not exist, then find returns an empty list with an exit code of zero. Now let's search for all JSON files. If you execute this command without the quotation marks around the glob pattern, then you may expect the terminal to also print a list of JSON files. However, notice that the terminal only prints a list of package.json files. Suppose we rename the package.json file in the root of the current directory to package-x.json . If we execute the previous find command, then notice that the terminal only prints this package-x.json file. Without the quotation marks, Bash expands the glob pattern and will replace it with the first file in the current directory that matches this pattern, which is package-x.json . To ensure that Bash does not expand the glob pattern and behave non-deterministically, wrap the glob pattern in quotation marks. Now, revert the renaming of package-x.json back to package.json . Currently, this project has no empty directories: Let's create an empty directory: When we search for empty directories within this project, the terminal will print the empty-dir directory. Since relative paths start with ./ to indicate the current directory, the argument passed to the -path test must begin with either * or ./ to allow the glob pattern to match the leading segment of a relative path. If we tried to locate package.json files with -path and forgot to add these prefixes to the glob pattern, then the find command returns an empty list. Prepending * or ./ to the glob pattern allows the find command to correctly match for package.json files via their relative paths. Let's find all package.json files within the packages sub-directory: The -type test filters out directories/files based on what the user is looking for. If the user only wants the find command to limit its search to files, then the -type test must be passed f for "file." The following command prints all of the files within the current directory. If the user only wants the find command to limit its search to directories, then the -type test must be passed d for "directory." The following command prints all of the sub-directories within the current directory. To search for multiple types, join the types together and separate each type with a comma. The -type test supports additional types: Proceed on to the second part of this blog post, which dives into the grep command.

Thumbnail Image of Tutorial Searching with find and grep

I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

This has been a really good investment!

Advance your career with newline Pro.

Only $30 per month for unlimited access to over 60+ books, guides and courses!

Learn More

Testing a Go and chi RESTful API - Route Handlers and Middleware (Part 2)

Disclaimer - If you are unfamiliar with writing a simple unit test for a route handler of a Go and chi RESTful API, then please read this blog post before proceeding on. Go's testing library package provides many utilities for automating the testing of Go code. To write robust tests for Go code, you must already understand how to write a basic Go test suite that contains several TestXxx functions. Writing tests for code, especially within the context of test-driven development (TDD), prioritizes the code's correctness over the code's flexibility to adapt to new/updated requirements. The guarantee of less unexpected regressions offsets the upfront cost of spending more time to write tests alongside application code. In a fast-paced, high-pressure environment, it can be difficult to convince other team members and stakeholders of the value in testing code when time is an extremely limited resource. Another factor that must be considered is the amount of code covered by the tests. If the tests cover only a small percentage of the application code (or a small subset of use cases), then the benefits of having these tests probably won't outweigh the benefits of adding new features or improving existing features. Plus, anytime you decide to refactor the application code, you will also have to update the corresponding tests to reflect these changes. When time is so valuable, the time spent on writing tests could have been spent elsewhere. Therefore, to fully benefit from tests, you must write enough tests such that they cover a large percentage of the application code. If a RESTful API exposes multiple endpoints, then testing a single route handler won't bring much value for the time spent writing it. Testing RESTful APIs built with Go and chi requires testing not only all of the route handlers, but also, the chi /custom middleware handlers. Let's write tests for... Clone a copy of the Go and chi RESTful API (with a basic test for a single endpoint) from GitHub to you machine: This RESTful API specifies five endpoints for performing operations on posts: If you would like to learn how to build this RESTful API, then please visit this blog post . Run the following command to install the project's dependencies: Note : If you run into installation issues, then verify that the version of Go running on your machine is v1.16 . There is a single test within the routes/posts_test.go file: TestGetPostsHandler . It tests the route handler for the GET /posts endpoint, and it mocks out the GetPosts function called by the route handler to avoid sending a network request to the JSONPlaceholder API when executing tests. Compared to testing route handlers for GET requests, testing route handlers for other HTTP methods (e.g., POST and PUT ) involves slightly more code to test requests that carry data in the form of an optional request body: Let's write a test for the POST /posts endpoint. Before starting, we must first review the route handler for this endpoint ( Create ) in the routes/posts.go file. ( routes/posts.go ) To test the route handler Create , we must first mock out the CreatePost function to avoid sending a network request to the JSONPlaceholder API when executing tests. CreatePost accepts a request body and returns an HTTP response and error (if encountered). Therefore, the mock function must follow the same function signature as CreatePost , like so: CreatePost is defined on type JsonPlaceholderMock . The request body must contain the following information: Since this request body (JSON data) must be passed as type io.ReadCloser to CreatePost , it must be read into a buffer, converted into a byte slice and then decoded into a Go struct so the data can be accessed normally. When a POST /posts request is sent to the JSONPlaceholder API, it returns a response that contains the newly created post. This post contains the exact same information as the request body with an additional Id field. This Id field is set to 101 to imply that a new post was added since there is a total of 100 posts, and each post has an Id field set to 1 , 2 , 3 , etc., up to 100 . The JSONPlaceholder API doesn't actually create this new resource, but rather, fakes it. So anytime you send a request to POST /posts , the response returned will have a newly created post with an Id field set to 101 . In our mock function, let's create this dummy data to send back in the response. Encode this struct to JSON via the json.Marshal method and return it within the body of a HTTP response. This HTTP response should return with a 200 status code to indicate a successful request. Note : This HTTP response returned must adhere to the http.Response struct , which accepts an integer value for its StatusCode field and a value of type io.ReadCloser for its Body field. The ioutil.NopCloser method returns a ReadCloser that wraps the Reader (in this case, bytes.NewBuffer(respBody) , which prepares a buffer to read respBody ) with a no-op Close method, which allows the Reader to adhere to the ReadCloser interface. Putting it altogether... With the mock function now implemented, let's write the test for the route handler Create for POST /posts . Start by naming the unit test TestCreatePostHandler , like so... Then, write this test similar to the TestGetPostsHandler test, but with several adjustments to account for it testing a POST route handler: Putting it altogether... To test the chi logger middleware handler ( middleware.Logger ), we must first understand the implementation details of this handler function: ( go-chi/chi/middleware/logger.go ) The middleware.Logger function only calls a package-scoped function, DefaultLogger , which logs information for each incoming request. ( go-chi/chi/middleware/logger.go ) This package-scoped function accepts a handler function and returns a handler function. Therefore, we can write a test that involves passing a simple route handler to middleware.DefaultLogger and calling middleware.DefaultLogger 's ServeHTTP method with a response recorder and created request: Try adding more endpoints and writing tests for those endpoints' route handlers.

How to Test Your First React Hook Using Testing Library

In previous posts we learned: In this post, we're going to write tests for a custom React hook. We're going to create a custom hook that will uppercase a given text string. This hook will be connected to an input and whenever a user changes the input value this hook will automatically uppercase the value. Let's write the hook. Create a file called useUppercase.ts In this file, we create a custom hook function useUppercase() . It accepts a string as an initial argument. We transform this string using .toUpperCase() and then store the result value in a local state. Also, we create a function update() . This function will be a part of the public API. With this function, components will be able to update the current value. Finally, we use useEffect() to re-render the hook if the initialValue gets changed. This, for example, happens when the component gets new props and passes the new initial value to the hook. In this case, we need to update the local state with the new value from the component. Now, let's test the hook! To test hooks, we're going to use React Hooks Testing Library . It gives us utilities for testing hooks without even rendering a single component. Let's install it: Now, we create a file useUppercase.test.ts . In this file, we import our hook and describe our first test: The first thing we want to test is that the hook returns a given initial value in the upper case. With React Hooks Testing Library, we don't need to render a whole component, instead, we render the hook itself with a special function called renderHook() : The renderHook() function returns an object with the result field. We can access the current render result with the current field. It contains the object our hook returns. We can use autosuggestions to select a field to test against: The coolest feature is readability. We don't need to create extra infrastructure code to test hooks in isolation. It just works! Another thing we want to test is that when we call update with a new string, the hook's value updates. Let's write another test: The current render result contains a reference to our update() method, so we can use it to simulate a change. Notice that we need to use act() . It is required for the hook to update the values inside of it. According to the documentation : The last thing to cover is a case when the hook gets a new initialValue . In this case, we need to update its values and re-render the component that is using them. In this test, we access not only the result but also the rerender() method. This method renders the hook with another initial value. Also, this time we use props to pass initial values. They help us to keep the code shorter and more readable. In general, we pass the initialProps object to options of the render() method. When we need to re-render the hook, we can pass updated values for this object. The library infers the type of the object so we can use autosuggestions here as well:

Thumbnail Image of Tutorial How to Test Your First React Hook Using Testing Library

Building a Simple RESTful API with Go and chi

The Go programming language is designed to address the types of software infrastructure issues Google faced back in late 2007. At this time, Google predominantly built their infrastructure using the programming languages C++, Java and Python. With a large codebase and having to adapt to rapid technological changes in both computing and key infrastructure components (e.g., multi-core processors, computer networks and clusters), Google found it difficult to remain productive within this environment using these languages. Not only does Go's design focus on improving the productivity of developers/engineers, but Go's design incorporates the best features of C++, Java and Python into a single statically-typed, compiled, high-performance language: Using Go and a lightweight router library, such as chi , writing and launching a simple RESTful API service requires little time and effort, even if you have no experience with Go. chi 's compatibility with the Go standard library package net/http , optional subpackages (middleware, render and docgen) and consistent API allows you to compose mantainable, modular services that run fast. Plus, these services can be deployed to and thrive in a production environment . If you have previously built RESTful APIs using Node.js and a minimal web application framework, such as Express.js , then you will find this to be quite similar! Below, I'm going to show you: To install Go, visit the official Go downloads page and follow the instructions. If you want your machine to support multiple versions of Go, then I recommend installing GVM (Go Version Manager) . Note : This installation walkthrough will be for Mac OS X systems. Run the following command to install GVM to your machine: Either... A.) Close the current terminal window and open a new terminal window. Or... B.) Run the source command mentioned in the output to make the gvm executable available to the current terminal window. Run the following command to install the latest stable version of Go (as of 02/21, v1.16): Notice how the installation fails. The following error message is printed within the output: If we check the contents of the log file /Users/kenchan/.gvm/logs/go-go1.16-compile.log , then the actual cause of the failure will be shown: Because the go executable could not be found, and GVM assumes that this go executable should be Go v1.4, let's install Go v1.4 from binary: Apparently, there is an known issue with installing Go v1.4 on certain versions of Mac OS X. Instead, let's install Go v1.7.1 from binary: Then, set the go executable to Go v1.7.1: Set the environment variable $GOROOT_BOOTSTRAP to the root of this Go installation to build the new Go toolchain, which will provide the necessary tools to compile ( build ), format ( fmt ), run ( run ) source code, download and install packages/dependencies ( get ), etc.: Finally, let's install the latest stable version of Go and set the go executable to it: Note : The --default option sets this version of Go as the default version. Whenever you open a new terminal window and execute go version , this default version will be printed. Create a new project directory named "go-chi-restful-api": This RESTful API service will offer the following endpoints for accessing/manipulating "posts" resources: A post represents an online published piece of writing. It consists of a title, content, an ID and an ID of the user who authored the post: These endpoints will interface directly with JSONPlaceholder , a fake API for testing with dummy data. For example, when it receives a GET /posts request from a user, our Go RESTful API will check for this route and execute the route handler mapped to it. This route handler will send a request to https://jsonplaceholder.typicode.com/posts and pipe the response of that request back to the user. This project will be comprised of two Go files: Create these files within the root of the project directory: ( main.go ) A Go source file begins with a package clause. All source files within the same folder should have the same package name. main happens to be a special package name that declares the package outputs an executable rather than a library and has a main function defined within it. This main function is executed when we run the Go program. This program imports three standard library packages and one third-party package: Inside of the main function... ( posts.go ) This source file contains the sub-router for the /posts route and its sub-routes ( /posts/{id} ). Here, we import three standard library packages and one third-party package: An empty struct postsResources is defined to namespace all functionality related to "posts" resources. func (rs postsResource) Routes() chi.Router defines the Routes method on the struct postsResource . This method returns an instance of the chi router that handles the /posts route and its sub-routes. Recall previously how we attached this sub-router to the parent router in main.go : Note : A struct is a typed collection of fields. In this Routes function, several endpoints for /posts and its sub-routes are defined on this sub-router. Each method call on the r sub-router instance corresponds to a single endpoint: Along with the Routes function, each of these request handler functions is also defined on the struct postsResource . Let's explore the body of a request handler, List , to understand how request handlers work. When the user sends a GET request to /posts , the request handler for this endpoint sends a GET request to https://jsonplaceholder.typicode.com/posts via the http.Get method to fetch a list of posts. If an error is encountered while fetching this list of posts ( err is not nil ), then the http.Error method replies to the original request with the err object's message and a 500 status code ( http.StatusInternalServerError ). If the list is fetched successfully, then close the body of this response ( resp ) to avoid a resource leak. Set the "Content-Type" header of the response ( w , the one to send back to the user) to "application/json" since the posts data is in a JSON format. To extract the list of posts from resp , copy resp.Body to the w buffer with io.Copy , which uses a fixed 32 kB buffer to copy chunks of up to 32 kB at a time. Then, send this response with the retrieved posts back to the user. Once again, if an error is encountered, then reply to the original request with an error message and a 500 status code. Note : _ is commonly used to denote an unused variable. It serves as a placeholder. When sending a POST/PUT request to the RESTful API service, the body of this request can be accessed via r.Body . When the user sends a GET request to /posts/1 , the router must first pass the request through the PostCtx middleware handler. This middleware handler... In a request handler, values from the request's Context can be accessed by the value's corresponding key. So to get the URL parameter we extracted in the previous step and set as a Context value with the key id , call r.Context().Value("id") . Because both keys and values are of type interface{} in Context , cast this URL parameter value as a string . The http package provides shortcut methods for sending GET and POST requests via the Get and Post methods respectively. However, for PUT and DELETE requests, use the newRequest method to create these requests. You must explicitly pass the HTTP method to newRequest and manually add request headers. client.Do sends the HTTP request created by newRequest and returns an HTTP response. Once again, if an error is encountered, then reply to the original request with an error message and a 500 status code. We could have used io.ReadAll to extract the response body, like so... However, io.ReadAll is inefficient compared to io.Copy because it loads the entirety of the response body into memory. Therefore, if the service must handle a lot of users simultaneously, and the size of resp.Body is large (i.e. contents of a file), then it may run out of available memory and eventually crash. To run install RESTful API service, first install all required third-party dependencies. In this case, there is only one third-party dependency to install: github.com/go-chi/chi . Let's add the project's code to its own module using the following command: If you have previously worked with Node.js, then you can think of go.mod as Go's package.json . By having the project's code in its own module, the project's dependencies can now be tracked and managed. Run the following command to install the project's dependencies and generate a go.sum file that contains checksums of the modules that this project depends on: These checksums are used by Go to verify the integrity of the downloaded modules. If you have previously worked with Node.js, then you can think of go.mod as Go's package.json and go.sum as Go's package-lock.json . Run the following command to run the command: If you would like to run the service on a different port, then set the environment variable PORT to a different port number: Test the service by sending a POST request to /posts : It works! Try sending requests to the other endpoints. chi offers a lot of useful, pre-defined middleware handlers via its optional middleware package. Visit this link for a list of these middleware handlers. One such middleware handler is Logger , which prints on every incoming request: Let's import the github.com/go-chi/chi/middleware package and add the Logger middleware to main.go : ( main.go ) In a separate terminal tab/window, send the same POST request to /posts : Information about this request is logged to the terminal. Click here for a final version of the RESTful API. Try adding more routes to this RESTful API! JSONPlaceholder provides five other resources (comments, albums, photos, todos and users) that you can create endpoints for.

Thumbnail Image of Tutorial Building a Simple RESTful API with Go and chi