Giter Club home page Giter Club logo

quando's Introduction

Quando

This project is unmaintained. ts-pattern is a better execution of the idea.

npm bundle size GitHub Language grade: JavaScript

๐ŸŽต Tell me when will you be mine? / Tell me quando quando quando ๐ŸŽต

Install

npm i quando
yarn add quando

Motivation

JavaScript has poor support for conditional expressions, and handling scenarios with multiple clauses is impossible. It's awkward when handling conditions in JSX which encourages an expression oriented approach and doesn't provide conditional elements found in a templating language like Handlebars.

Some proposals would bring more powerful conditional expressions to JavaScript like do and pattern matching, but they are a long way off and may never happen. In an ideal world, this library would be made redundant by these proposals making it into the language. However, Quando is for the time we spend waiting.

Here's an example that handles the status of an API call using the Match function:

function Example() {
  const { status, error, data } = useQuery("repoData", () =>
    fetch("https://api.github.com/repos/richeyryan/quando").then(res =>
      res.json(),
    ),
  );

  return (
    <div>
      {Match(status)
        .where("error", () => <>"An error has occured: " {error.message}</>)
        .where("loading", "Loading...")
        .end(() => (
          <>
            <h1>{data.name}</h1>
            <p>{data.description}</p>
            <strong>๐Ÿ‘€ {data.subscribers_count}</strong>{" "}
            <strong>โœจ {data.stargazers_count}</strong>{" "}
            <strong>๐Ÿด {data.forks_count}</strong>
          </>
        ))}
    </div>
  );
}

Functions

Compatibility

The API aims to avoid clashing with current or potential future JavaScript features. We avoid reserved words where possible, and When is capitalized to avoid conflicts with the pattern matching proposal.

Fluent Interface

Each function has a chainable API or fluent interface. You must complete the chain with the end method, which will return the result of your expression. You can also provide the default value with the end method if there are no matches in your condition.

Lazy Evaluation

The result parameter of any condition can be a function. If the condition is truthy, the function gets called, which prevents issues like in the example above where we get an error if we try to read data.name before it's defined.

When

The equivalent of an if statement, returns the first clause where the condition is truthy. Returns the default if there is no match.

import { When } from "quando";

When(status === "loading", <Loading />)
  .elseWhen(status === "error", <Error message="Failed to load user" />)
  .elseWhen(status === "success", <User user={user} />)
  .end();

Unless

Returns the clause if the condition is falsy. Returns the default if the condition is truthy.

import { Unless } from "quando";

Unless(user, "Select a user to continue");

Match

A very rough approximation of pattern matching. Basically an expression version of a switch statement.

The first parameter of where can be a value that strictly matches (===) the comparable passed to Match. Otherwise, it can be a function which takes the comparable as a parameter and returns true if it matches or false if it doesn't.

The second parameter can be any value or a function that is called only when the comparable is matched.

Match("John")
  .where("John", "guitar")
  .where("George", "guitar")
  .where("Paul", "bass")
  .where("Ringo", "drums")
  .end();

Examples

Examples of using each function can be found in the examples folder. You can run them like this:

yarn build
node examples/examples.js

Any contributions of interesting examples would be much appreciated.

Extending the library

Each of the functions above are factories that create an instance of a class. There is a class for each of the functions. Each class is a facade over the Matcher class, they make the public fluent interface and each call passes through to the Matcher which handles the actual matching logic.

You can import the Matcher class and the extractResult function which helps with results that are passed as functions. Using them both you can create your own factory function and inject your own matching logic into the Matcher class.

quando's People

Contributors

richeyryan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.