npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

lodash-decorators

v6.0.1

Published

A collection of decorators using lodash at it's core.

Downloads

271,485

Readme

lodash-decorators

Decorators using lodash functions. View the API docs for more in depth documentation.

Build Status npm version

Install

npm install --save lodash lodash-decorators

Polyfills

This library requires Map and WeakMap to be available globally. If Map or WeakMap is not supported in your environment then use a polyfill.

Usage

For more in depth documentation please visit Lodash

Decorators are exported as both start case and lower case.

import { Debounce } from 'lodash-decorators';

is the same as

import { debounce } from 'lodash-decorators';

They can also be imported directly.

import Debounce from 'lodash-decorators/debounce';

Decorators

These decorators are included in the package. These are also exported as lowercase for those who prefer lowercase decorators.

  • After
  • AfterAll
  • Ary
  • Attempt
  • Before
  • BeforeAll
  • Bind
  • BindAll
  • Curry
  • CurryAll
  • CurryRight
  • CurryRightAll
  • Debounce
  • DebounceAll
  • Defer
  • Delay
  • Flip
  • Flow
  • FlowRight
  • Memoize
  • MemoizeAll
  • Mixin
  • Negate
  • Once
  • OnceAll
  • OverArgs
  • Partial
  • PartialRight
  • Rearg
  • Rest
  • Spread
  • Tap
  • Throttle
  • ThrottleAll
  • ThrottleGetter
  • ThrottleSetter
  • Unary
  • Wrap

Example

import { Debounce, Memoize } from 'lodash-decorators';

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  @Debounce(100)
  save(date) {
    return this.httpService.post(data);
  }

  @Memoize(item => item.id)
  doSomeHeavyProcessing(arg1, arg2) {}
}

Optional Params and Casing

If a decorator does not require params or has optional params then the decorator does not require invocation. Decorators are also exported in lower case as well as start case.

Example

// These are both valid decorator usages.
class Person {
  @Memoize()
  doSomething() {}

  @Memoize
  doSomething2() {}

  @memoize()
  doSomething3() {}

  @memoize
  doSomething4() {}
}

Partials

Some decorators work slightly differently than you would expect them to work than lodash.

  • Partial
  • PartialRight
  • Wrap

These can take a Function as their first argument or a String. If the argument is a String then a Function is resolved from the current object.

Example

import { Partial, Wrap } from 'lodash-decorators'

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  getName(type) {
    return type === 'firstName' ? this.firstName : this.lastName
  }

  @Partial('getName', 'firstName')
  getFirstName() {}

  @Partial('getName', null)
  getLastName() {}

  @Wrap('getName')
  getUpperCaseName(fn) {
    return fn().toUpperCase();
  }
}

const person = new Person('Joe', 'Smith');

person.getFirstName(); // 'Joe'
person.getLastName(); // 'Smith'
person.getUpperCaseName(); // JOE SMITH

Composition

You can use methods like compose and flow similiar to partials. The arguments are resolved the same way partials are resolved.

Example

import { Flow } from 'lodash-decorators'
import { kebabCase } from 'lodash';

class Person {
  @Flow('getName', kebabCase)
  logName;

  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  getName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const person = new Person('Joe', 'Smith');

person.logName(); // joe-smith

Instance Decorators

Normally decorators are applied to the prototype method of the class you are working with, but with some of these decorators that is not the desired behavour. These decorators are applied at the instance level.

  • Debounce
  • Throttle
  • Memoize
  • After
  • Before
  • Curry
  • CurryRight
  • Once
  • Flow
  • FlowRight
  • Rearg
  • Negate
  • Flip
  • Bind
  • Partial
  • PartialRight

Mixin

You can mixin methods into a class by using the Mixin decorator.

Example

import { Mixin } from 'lodash-decorators';

const MyOtherApi = {
  someCoolMethod() {
    // Do something cool
  }
};

@Mixin(MyOtherApi)
class Person {}

Person.prototype.someCoolMethod === MyOtherApi.someCoolMethod; // => true

Attempt

You can wrap a method in a lodash attempt method.

Example

import { Attempt } from 'lodash-decorators';

class Person {
  @Attempt()
  throwAnError() {
    throw new Error();
  }

  @Attempt()
  doNotThrowAnError() {
    return '0_o';
  }
}

const person = new Person();

let result = person.throwAnError();

result instanceof Error; // => true

result = person.doNotThrowAnError();

result === '0_o'; // => true

Bind

Bind takes arguments based on lodash's bind and binds the Function to the current instance object.

Example

import { Bind } from 'lodash-decorators'

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  @Bind()
  getName() {
    return `${this.firstName} ${this.lastName}`;
  }

  // It can also function as a partial
  @Bind('Joe')
  getUpperCaseName(name) {
    return name.toUpperCase();
  }
}

const person = new Person('Joe', 'Smith');

person.getName.call(null); // Joe Smith
person.getUpperCaseName(); // JOE

You can also bind entire classes with bindAll or bind.

Example

import { BindAll } from 'lodash-decorators'

@BindAll()
class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  getName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const person = new Person('Joe', 'Smith');

person.getName.call(null); // Joe Smith

v4 Breaking Changes

Version 4 is a rewrite of the library and has many breaking changes.

Not all decorators can be applied to or forced on getters/setters.

Only certain decorators make sense to be applied to getters/setters. Before you could specify the target of the decorator like debounce.set(15). This behavior is removed and decorators that make sense to apply to getters/setters are configured to be applied to methods and either the getter or the setter. For example:

class MyClass {
  // This only gets applied to the setter as it doesn't make sense to apply it to the getter.
  @Debounce(1000)
  get value() {
    return this._value;
  }

  set value(val) {
    this._value = val;
  }

  @Debounce(15)
  fn() {}
}

This keeps the API cleaner and doesn't require the developer to know how the decorator applies to the descriptor. Some decorators have explicit version that apply to either getters of setters, such as ThrottleGetter and ThrottleSetter.

No longer force instance decorator onto prototype

There is no longer a Proto decorator attached to instance decorators. Most instance decorators now have a counterpart that applies to the prototype instead of the instance. Debounce.Proto() is now DebounceAll().

All decorators now take arguments

All decorators now take arguments. So instead of @Once you would do @Once(). This keeps the API consistent and doesn't require the developer to remember which decorators take arguments.

Removal of extensions and validation package

All extensions like enumerable have been removed in favor of core-decorators. There may be some slight over lap like debounce and throttle. Fair warning, instance decorators may not play nice with other implementations of instance decorators.

We want to keep lodash decorators focused specifically on lodash specific functions.

Prototype decorator order no longer throws an error

If a prototype decorator comes after an instance decorator it will be ignored since there is no way to apply it in the chain.

Other breaking changes

  • Attempt now takes an argument to line up with lodash API.
  • Bind used on a class no longer delegates to BindAll. Use BindAll instead.
  • Curry, Partial, Flow, FlowRight are now instance decorators.

v4 Improvements

  • Ships with TypeScript typings.
  • Predictable performance.
  • Improvements to Bind decorator.
  • Improved API for decorator factory.
  • More and better unit tests.
  • Better performance with instance decorators.
  • Single imports with import { Debounce } from 'lodash-decorators/debounce';
  • Composition decorators can be used on properties. These will generate the composed function.