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

How to Install Types for Packages

When you develop an app you often use some third-party packages as dependencies. Not all of them are written in TypeScript, but many provide type declarations for a developer to be able to include those in a project. The biggest repository with type declarations is DefinitelyTyped . It contains type declarations for packages like React, Redux, Mobx, and many others. Some packages already have .d.ts files in them. These files contain type declarations. If your dependency package has it, you won't need to install types manually. If a package doesn't have .d.ts file and is written in plain JavaScript, you might need to find type declarations yourself. Let's say you want to use react-transition-group package. You installed the package itself and try to import it in a React + TS project: IDE will show an error that the project can't be compiled: A package may recommend installing types from a DefinitelyTyped or another repository in its documentation. If so, run all the commands recommended in docs. Otherwise, try to install types from DefinitelyTyped manually. In the case of react-transition-group : Usually, type declaration name consists of the @types/ prefix and the package name after it. (In some rare cases you may want to google the name first.) When types are installed IDE should hide the error and compile the project.

Thumbnail Image of Tutorial How to Install Types for Packages

wtf are Higher Order Components?

The Higher Order Component (HOC) pattern is used frequently in React libraries, so it's worth knowing. Below I'm going to show you what a HOC is, how to use one, and how to create your own.The Higher Order Component pattern reduces the amount of repetitive code you write as your app grows. A Higher Order Component provides common functionality that other components reuse. The Higher Order Component (HOC) pattern is used frequently in React libraries, so they're worth learning. When we talk about a “higher order” function, what does “order” even mean? Let’s look at a simple function first: Function  increment()  is a regular function that takes a  number  and returns the sum of this number and  1 . It is a normal, first-order function because it takes “normal” values as arguments and returns a normal value. A  higher order  function, is a function that either: (or both). Consider the following: Function  twice()  is a function that takes another  function  as an argument and returns a  function  as a result—that makes it a  higher order function . We’d use it like this: So the idea with a higher-order function is that we  generate a new function  that has  new abilities  based on the original function. Higher Order  Components  carry the same idea, but in the realm of React components. A Higher Order Component is a function that takes a  component  as an argument and returns another  component  as a result of some processing. Let’s see what a higher order component looks like in practice. First, look at this pseudocode of a higher order component. The higher order component takes a component, transforms it, and returns a new component. In code, that means we structure it like this: The result of applying  higherOrderComponent  to  SomeComponent  is the new component,  NewComponent . If you are struggling to wrap your head around how this works, remember our definition: A higher order component is a component/function that takes any component and returns another component - with modified functionality. For our next example, say we want to build a component to syntax highlight code in multiple languages - and support a dark mode. This is what our components look like: and These components print out code snippets ( codeSample ). Say, that we want to support a “night mode”, so that it’s easier to read at night. To keep it simple, all our “night mode” is going to do is add a  backgroundColor  of  wheat . This is what the component will look like: Our higher order component,  withNightMode , adds new styling with a slightly darker background by adding a  div  around  WrappedComponent . What is  WrappedComponent ?  Any component we want! We pass  WrappedComponent  in as an  argument  and  return a new component  as the result. Hence the term, “Higher Order Component”. Below, we use the component that is returned by our High Order Component function: You can try it out in this Code Sandbox 👆 In the code above, we use the higher order component  withNightMode  to transform our input components into versions that display with a “Night Mode” style. What’s cool is that we did not have to code this behavior in the components themselves. Rather, we made a higher order component that applies this behavior to any component we pass it. Of course, Higher Order Components can get more complicated. You definitely want to use  types  to ensure that your HOC and the components themselves are compatible. And we show some detailed examples of how to do that in  Fullstack React with TypeScript .

Thumbnail Image of Tutorial wtf are Higher Order Components?

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

What Rust Is All About: A Small Tour

In this post, we'll try to give you a taste of Rust's key features so you may get a feel for the language. We'll touch on the type system, some handy functional features, traits, and more!Rust is a systems programming language that was conceived at Mozilla and is now developed by a larger community. Initially, its purpose was to help rewrite portions of Firefox's codebase (largely C/C++) to improve its safety and security. It has since enjoyed growing adoption in fields such as Rust is a statically typed language that emphasizes static code analysis, helpful compilation errors, convenient and comprehensive tooling, memory and concurrency safety, sheer performance, and abstractions that incur no (or little) runtime cost. Its memory model avoids the overhead of a garbage collector, but at the same time, the language's compiler enforces a set of rules that effectively prevent memory errors common in C/C++ applications. This is not a comprehensive "learn Rust in one hour" guide. It should, however, give you a little taste of what the language is about and help you decide if it's for you! We will guide you through some of the key concepts you'll inevitably stumble into in Rust code, including custom types, error handling, ownership, closures, higher-order functions, iterators, pattern matching, and traits. This guide is intended for people with some prior high-level programming experience, though which particular language(s) you've previously worked with shouldn't overly matter. If you'd like to give the snippets a run, the easiest way is to use the Rust Playground online. If you prefer to run things locally, the Getting Started chapter from the Book will help you get your environment and a "Hello, World" project set up! A comprehensive static type system means safer code and fewer manual tests that need to be written. The more information you can encode in the type system, the more Rust can check for free during compilation, allowing greater confidence in the correctness and reliability of your programs! Rust has structs. Structs have fields. Rust also has enums for when a thing can be either this or that. Enums have variants. An enum value can only be set to one variant. Enum variants can hold data. Both structs and enums can be generic and accept arbitrary concrete types inside. This is possible by declaring type variables in angle brackets ( <> ). In the example above, the compiler will deduce that foo is of type Wrapper<f64> . Wrapper<T> is not a dynamic type! It's resolved during compilation. Oh, and by the way, the let statement is how you declare a local variable. It accepts type annotations, but most of the time they're not necessary - Rust might be a disciplined and strongly-typed language, but it's fairly smart and able to infer types itself a lot of the time. You can add methods to any type you define using impl blocks. Rust doesn't have anything like a try...catch statement. Instead, there is the Result<T, E> type, defined more or less like so: Two types should be provided here. T is the type of the actual return value. E is the type of error data. A function that may fail should return a Result - like the one below that attempts to sum a vector, but fails if it's empty. The unit type () is often used to signify nothing is returned. In this case, we're basically saying we don't want to add any extra error information if the function fails - we just want to know that it failed. In "real" Rust code, it's generally a good idea to provide an error type that implements the std::error::Error trait, but that's outside of our scope right now. If we want to use our my_sum function now, we cannot ignore the fact it might produce an error. The snippet below won't work. This doesn't compile. The compiler tells us the result of summing is really a Result , and so cannot be added to a float. First, we need to unpack the value inside the Result and handle the potential error. One verbose way to handle the error (by crashing the whole application) looks like this: This match statement isn't some special construct for error-handling. It can be used for pattern-matching against any enum. We'll talk about it later. This is the power of Rust's approach to error-handling: there's no magic. You get to use the same control flow as you would for the rest of your code. There's of course shorthand for the above: Another strong point for Rust is that even if you don't use the Ok value (sometimes there is none), the compiler will still nudge you about having unchecked results. Forgetting about potential problems isn't easy. Unless we go into unsafe hackery, Rust doesn't have null values. Let's define a struct Foo. Any initialized variable of the type Foo must hold a valid Foo with a valid f64 number inside. Thanks to that, if you write a function that accepts Foo , you don't have to worry about handling a potentially null value. The compiler will make sure only valid, initialized data gets passed to the function. What if we want to express that a variable can hold nothing? This is one place where generic enums come in handy. The standard library defines this Option type: If we wrap our Foo in an Option , we can express that we might have a Foo or nothing. Every computer program has to manage the memory used for its data. When some data is no longer used, the memory it occupied should be freed. After it is freed, the program should never attempt to access that data again, or face bugs. Most modern languages use garbage collectors . Thanks to those, this de-allocation and proper use are not something the programmer needs to be concerned with. This, however, introduces some performance overhead. Unlike most high-level languages, Rust doesn't have a garbage collector. Instead, there's the model of ownership and borrow checking. Ownership is a key concept in Rust. The idea is that, at any time, every bit of data in memory has exactly one owner. When that owner goes out of scope, the data is tossed out. It is also possible to create references to owned data. These do not affect how long the data lives, but for your program to compile, the compiler has to ascertain that the references aren't used after the owner goes out of scope and the data is no more. If you try to compile the above snippet, you'll get this: Try to comment out the last println! statement and run the snippet then! By default, a reference is immutable. To create a mutable reference, you have to add the mut keyword like so: The first mut keyword allows mutation to the owned data at all. The &mut foo creates a mutable reference, which is then stored in foo_ref . *foo_ref dereferences the reference to get access to the underlying data and modify it through assignment. You can have many immutable references, but you can only have one mutable reference. While you hold a mutable reference, you cannot use the owner or have any other (mutable or not) reference. This is to prevent data races and mistakes. All illegal use of references causes compilation errors and forces you to fix your code before it ever has a chance to see production! One amazing thing about Rust is it brings some high-level abstractions inspired by cutting edge languages to the world of systems programming. Rust supports closures - anonymous functions capable of dynamically capturing the variables from the encompassing scope. These can be treated like any other value and assigned to variables. Those variables can then be called the same way regular functions can. Notice that num_printer prints two numbers, but they're passed through different mechanisms. The x argument has to be provided when calling num_printer , just like with named function. num_to_capture is implicitly captured by num_printer when the function is defined. This becomes much more interesting when combined with higher-order functions - functions that accept other functions as arguments and/or return a function. Say a third-party library defines a function called perform_calculations and allows you to extend the behavior of it by providing a callback. This is your chance to get partial results printed for the user currently logged in. Iterators are a major feature of Rust. They can be very convenient. Ranges of numbers are iterators. Iterators can be iterated on in a for loop. A borrowing iterator can be created for any collection, e.g. an array. It's possible to turn your own custom types into iterators by implementing the Iterator trait, too. An example can be found here ! There's one more way to execute something on every element of an iterator. What if we want to reverse an array, add an m to every element, and then collect it into a vector of strings? What if we want to get the product of numbers from 1 to 5 (not inclusive)? fold lets us apply a function to the first and second elements, then to the result and the third element, and so on. Hopefully, this gives you a taste of the power of iterators. They're not just for looping over them; they're a convenient and powerful tool for transforming data. The best way to learn about all those methods is to browse the Iterator documentation. That's also where you can learn to implement custom iterators - all you need to do is implement the trait on your own type. Rust allows pattern matching and all the de-structuring goodness associated with it. An underscore ( _ ) is used as a catch-all - it matches anything. Tuples can be de-structured while we're pattern-matching against them. Underscores can also be used inside those patterns. Here's an implementation of Fizz buzz : Enums can be neatly de-structured too. Instead of matching specific values inside of structures, they can be captured in a variable. Traits essentially declare some functionality that concrete types may provide. Traits can be compared to interfaces in other languages or (more accurately) to typeclasses in Haskell. They are Rust's solution to the problem of code reuse. They can pretty much act as abstract types, too. One important property that traits have and interfaces in other languages do not is that traits can be implemented for foreign types - even built-in primitives. It's entirely possible to extend f64 with your own, custom trait. One example of a useful trait is the Iterator one. It's fairly straightforward to create a custom iterator. The one below returns positive integers in order, ad infinitum. After we have one defined, we can use it like any other iterator, including all of those convenience functions mentioned earlier. They are provided "for free" for anything that implements the Iterator trait. Since many operators are either implemented using traits or defer to a trait when faced with custom types, operator overloading is possible by implementing those traits. It's usually a reasonably straightforward endeavor. Here's how addition can be implemented. Trait bounds are what make generic programming powerful. Previously, we mentioned type variables. It's possible to declare those for functions, too. There's not much we can safely do with a value of an unknown type, though. What if we knew something more about it? What if we knew what traits it implements? Here we define the function print_it generically for any value that implements the Display trait and can therefore be printed as a user-friendly string. Thanks to the trait bound, we know we can safely print whatever type we get. It's important to stress that this isn't dynamic - the concrete types are inferred during compilation. When you call print_it(123.3) , the compiler (rather than the runtime) will check that f64 implements the Display trait, and then essentially create a function from the generic print_it definition specifically for the f64 type. What does it matter if this check is performed during compilation or runtime? If we ensure the correctness of types we pass around during compilation, type errors never have a chance to make it to production. It's much easier to rely on this kind of mechanism than to write extensive tests for all the problems we may create. There's some preferable syntax sugar for the generic print_it function. It helps us avoid thinking about type variables. Life is usually simpler that way! Whew! Hopefully, this helped you get a feel for Rust and shown it as the clever language it is. We've taken a glimpse of the type system, error handling, safety, functional patterns, pattern matching, and traits. Again, this tour isn't comprehensive; we've only scratched the surface here. The path to understanding the language and writing idiomatic code is much longer. Every journey has to start somewhere, though. We can only hope this was a good start, and that it got you hungry for more. Want to learn Rust properly? "The Book" is widely considered the best course; we cannot recommend it enough. You will learn everything we've mentioned here and more. Some alternatives:

5 GraphQL Clients and how to Pick One

There are a bunch of GraphQL clients that exist. How do you know which one is right for you? I’m going to discuss some of your options, but let’s cut to the chase: If you’re building a front-end web-app, I recommend you use Apollo Client. If you want to take my recommendation, you can just skip this post.  But for those of you who are making a years-long, fundamental architectural decision for your team - you might want to read below to get a lay of the land. Because GraphQL servers are typically over HTTP, you don’t  have  to use a client library at all. You can just use whatever HTTP request library you were already using and it will “work”.  GraphQL is in this sense, more of a language/protocol pair than a specific library and it will work fine in any language where you can form queries and parse JSON - making it suitable for mobile apps, compiled clients, etc.  So as we covered in the first chapter, you can query a GraphQL server using  curl , The  operationName  here is the name of your query. With curl , it would look like this: where the  ...  is replaced by the JSON string from above So why bother with a dedicated client? The big reason is because of  caching . Because our data is typed, and has a specific schema, intelligent clients can leverage that to cache data in clever, optimized ways. For example, an object that is loaded by one query may  already have been cached  by a previous, completely different query. And in these cases, the client can read from the cache instead of fetching from the server - resulting in a snappier user experience. There are lots of other nice features a dedicated client might have, too. Such as: All of the above can add up to a real-world advantage in programming time compared to just forming manual HTTP requests every time. So if you want to use a dedicated client, what are your options? Here’s a few: Let’s look a little closer at each one: graphql-request  is a JavaScript library that, as it’s namesake, makes it easy to make GraphQL requests. Here’s what the code looks like, taken straight from  the documentation What’s good: The drawbacks: It is super minimal - it doesn’t have any caching or most of the advanced features you’d get out of any of the clients below. Summary: It’s a great fit if you just want to make some quick requests without a lot of fuss. urql  gives you solid, lightweight choices in the default configuration, but is build to expand as you grow. They have a nice  page on the philosophy of urql  where they say: Here’s an example of making a query in a React app,  taken from their documentation Above, you can see that they call the  useQuery  hook to load the  TodosQuery  and then use that result in the rendered JSX. What’s good: The drawbacks: As of writing, only supports React, Svelte, and Preact. It’s the “2nd place” option , with all of the benefits and drawbacks of that role.  Also, while it’s lightweight to get started, you might find you’re adding so many add-ins that it would have been easier to just use Apollo. Summary: A solid library, with critical community mass, from a great team. It’s a good option. Relay Modern  a full-featured GraphQL client library and the original inspiration for Apollo.  What’s good: The drawbacks: Summary: An inspirational, tightly-React-integrated library with many good characteristics, but generally not used as widely as you’d expect, in part because it's opinionated and in part because Apollo took a huge amount of mindshare between Relay 1 and Relay Modern. I imagine that Relay Modern will ship a version that gets broader community adoption. Almost everyone I know in the industry that  would  use Relay is using Apollo instead. If you’re new to GraphQL and you’re trying to decide between Relay and Apollo, and you don’t know the difference, 9-times-out-of–10 you want Apollo. Like I mentioned above,  Apollo Client  today’s  de-facto  standard GraphQL library - works w/ React, Angular, Vue, etc. What’s good: The drawbacks: It’s relatively “heavy”. If you run into trouble, it’s a bit of a black box.  Summary: I use Apollo for newline and I’ve been incredibly happy. As often happens in open-source, there’s ecosystem benefits with going with the leader. There are more tutorials, bugs are fixed faster, and it’s an overall pleasant experience. Apollo also has tooling for building servers, so it’s a bit of a one-stop-shop for GraphQL services. It’s pretty obvious that I’m an Apollo fan. While there might be better choices for certain scenarios, if you’re building a straightforward web app, my recommendation is Apollo client. 

Who is Using GraphQL?

Quiz time: I’ll name three companies and you tell me what they have in common between them: Github. PayPal. Major League Soccer. The answer?  They all switched to GraphQL. They’re completely different organizations: version control hosting, a payments processor, and professional soccer league. But not only are their Engineering teams starting to use  GraphQL , they’ve started to see  significant success  with GraphQL  and the tools within the GraphQL ecosystem . Below, I’ll share a couple of reasons as to  why  they’ve found success with GraphQL and it should help inform if  your organization  should try using GraphQL. But before we get to that, I want to remind you: If you were wondering if GraphQL is “production ready” consider this: PayPal introduced GraphQL to products that were part of the PayPal checkout experience. In the article published by PayPal Engineering,  GraphQL: A success story for PayPal Checkout , they say that: Coming from a purely RESTful API perspective, the PayPal Engineering team recognized that  every  round trip made for their small atomic REST APIs during the checkout experience slowed rendering time, frustrated users and lowered checkout conversions Since a large effort was being made in attempting to construct performant and reliable REST APIs, the team also realized UI developers were spending less than 1/3 of their time building UI and most of their time figuring out where and how to fetch data, filtering/mapping over the data, and structuring API calls. Enter GraphQL… By going  all in with GraphQL , the PayPal Engineering team managed to solve  both their   developer experience and performance problems . They’ve recognized how GraphQL allows for  better performance  (clients only request the data they need!) and  better overall productivity . When the Major League Soccer (MLS) development team switch to Apollo in their React application, it helped them delete over  5000 lines of code . The MLS Engineering team relied on Redux (the Flux state management library) to share data/state between application components and for data fetching. Though Redux is a great library, a lot of developers have noticed that Redux and data-fetching with Redux often requires a decent amount of boilerplate and can be difficult to get started with. With Redux, the MLS team  recognized a large number of steps need to be taken to have data just be fetched from React components . Enter GraphQL… and Apollo One of the things that’s often misunderstood about Apollo is that the  Apollo Client  utility is a  complete state management  library. The common understanding of Apollo is as a  data-fetching  library – it’s very good at this, particularly because it will maintain a local cache and only fetch the data from the server that is neeed. However Apollo Client  also  provides an “internal state management” tool (like Redux, if you’re familiar). Meaning, you can use Apollo client  instead  of a state-management tool like Redux. By switching over to using Apollo Client for their data fetching needs, the MLS Engineering team cut away thousands of lines and greatly simplified their code. Though Github’s original public REST API was a source of inspiration to other companies, Github was one of the earliest large organizations to release their  public API in GraphQL  as well. Though Github’s REST API was structured in a sound manner, some of the issues the Github Engineering team had were around scalability concerns. The RESTful endpoints in the API were recognized to not be flexible and simultaneously were bloated by returning large amounts of “unnecessary” data. Enter GraphQL… The concluding paragraph in Github’s Engineering article,  The GitHub GraphQL API , summarizes the results the Github team has concluded with building their API with GraphQL. I could go on. and many, many other companies are seeing similar results. One of the best implications of using GraphQL is that you can  generate types  in TypeScript from your API to give you  strongly typed code from your API requests . But we’ll save that lesson for another day. If you not  only  want to learn React, GraphQL, Apollo, TypeScript, and Node but also  how  these technologies  work together to build production-ready apps , then  TinyHouse  is your guide. TinyHouse is a  hand’s on ,  project-based  Masterclass that walks you through building production-ready apps with  this growing and powerful technology stack . TinyHouse is more detailed than any other course we’ve made before  and contains: You can read more about Tinyhouse over here .

Thumbnail Image of Tutorial Who is Using GraphQL?