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

kaka-demo

v1.4.1

Published

![npm](https://img.shields.io/npm/v/@spfxappdev/utility) ![npm bundle size](https://img.shields.io/bundlephobia/min/@spfxappdev/utility) ![npm](https://img.shields.io/npm/dm/@spfxappdev/utility)

Downloads

392

Readme

@spfxappdev/utility

npm npm bundle size npm

This package contains some useful extensions for String and Array and some more functions that need less lines of code and make the code more readable. You can find the "nicer" and more user-friendly documentation here

Installation

npm i @spfxappdev/utility

Demo

You can find some examples/demo applications at codesandbox.io or GitHub

Functions

Usage

  1. import one of the functions in your project (in this example the function isset is imported)
import { isset } from '@spfxappdev/utility';

API


allAreNullOrEmpty

since @spfxappdev/utility@1.3.0

Determines if all of the the provided properties are null, undefined, or empty (or whitespace if string-value).

Examples
import { allAreNullOrEmpty } from '@spfxappdev/utility';

const emptyArr = []; //EMPTY
const obj = {}; //NOT null, undefined or empty
const notEmptyString = 'not empty';
const emptyString = '      '; // With whitespace

allAreNullOrEmpty(obj, notEmptyString); //false
allAreNullOrEmpty(emptyArr, emptyString); // true
allAreNullOrEmpty(obj, emptyString); // false
allAreNullOrEmpty(emptyArr, emptyString, obj, notEmptyString); // false

allAreSet

since @spfxappdev/utility@1.3.0

Determines if all of the the provided properties are set. (Not null or undefined)

Examples
import { allAreSet } from '@spfxappdev/utility';

const emptyArr = []; //EMPTY
const obj = {}; //NOT null, undefined or empty
const notEmptyString = 'not empty';
const emptyString = '      '; // With whitespace
let notSet;

allAreSet(obj) // true
allAreSet(emptyArr, emptyString); // true
allAreSet(obj, notEmptyString); //true
allAreSet(obj, emptyString); // true
allAreSet(obj, emptyString, notSet); // false
allAreSet(emptyString, undefined, null); //false

asyncFn

since @spfxappdev/utility@1.1.0

A wrapper function to handle a await function and their results/errors.

Examples

Instead of using this:

try {
    const result = await myAsyncFunction();
    console.log(result);
    //Do things with result
} 
catch (error) {
    console.error("An error occurred", error);
    throw "Whatever";
}
 

You can use the asyncFn-function like this

import { asyncFn } from '@spfxappdev/utility';

const [result, error] = await asyncFn(myAsyncFunction);
//with paramaters
const [result2, error2] = await asyncFn(myAsyncFunction, true, 2000);

//with "this" binding
const [result3, error3] = await asyncFn(this.myAsyncFunction.bind(this), true, 2000);

if(error) {
    throw "Whatever";
}

console.log(result);
//Do things with result

asyncFnAsResult

since @spfxappdev/utility@1.4.0

A wrapper function to handle an await function and their results/errors as IResult<TResult>

Examples

Instead of using this:

const result = new Result<any>();

try {

    result.value = await myAsyncFunction();
    console.log(result);
    //Do things with result
} 
catch (error) {
    result.error = error;
    console.error("An error occurred", error);
}

return result;
 

You can use the asyncFnAsResult-function like this

import { asyncFnAsResult } from '@spfxappdev/utility';

const result = await asyncFnAsResult(myAsyncFunction);
//with parameter binding
const result2 = await asyncFnAsResult(myAsyncFunction, null, param1, param2, ...);
//with "this" binding
const result3 = await asyncFnAsResult(myAsyncFunction, this, param1, param2, ...);

if(!result.success) {
    throw "Whatever";
}

console.log(result);
//Do things with result

catchFn

since @spfxappdev/utility@1.4.0

A function to wrap a specified function with a try-catch block and returns IResult<TResult>.

Examples

Instead of using this:

const result = new Result<any>();

try {

    result.value = myFunction();
    console.log(result);
    //Do things with result
} 
catch (error) {
    result.error = error;
    console.error("An error occurred", error);
}

return result;
 

You can use the catchFn-function like this

import { catchFn } from '@spfxappdev/utility';

const result = catchFn(myFunction);
//with parameter binding
const result2 = catchFn(myFunction, null, param1, param2, ...);
//with "this" binding
const result3 = catchFn(myFunction, this, param1, param2, ...);

if(!result.success) {
    throw "Whatever";
}

console.log(result);
//Do things with result

copyToClipboard

since @spfxappdev/utility@1.3.0

Writes the specified TEXT string to the system clipboard

Important: A DOM element must be in focus (e.g. click a button, focus a text box, etc.). You cannot simply paste text into the clipboard without the document being focused.

Examples
import { copyToClipboard } from '@spfxappdev/utility';

copyToClipboard(document.getElementById('myTxtBox').value);

cssClasses

since @spfxappdev/utility@1.0.0

A utility function for conditionally joining css class names together.

Examples
import { cssClasses } from '@spfxappdev/utility';

cssClasses('spfx-app-dev', 'theme'); // => 'spfx-app-dev theme'
cssClasses('spfx-app-dev', { theme: false });  // => 'spfx-app-dev'
cssClasses({ 'spfx-app-dev': true });  // => 'spfx-app-dev'
cssClasses({ 'spfx-app-dev': false });  // => ''
cssClasses({ spfx-app-dev: true }, { theme: true }); // => 'spfx-app-dev theme'
cssClasses({ spfx-app-dev: true, theme: true });  // => 'spfx-app-dev theme'
cssClasses('spfx-app-dev', { theme: true, active: false }, 'item');  // => 'spfx-app-dev theme item'
cssClasses(null, false, 'spfx-app-dev', undefined, 0, 1, { theme: null }, '');  // => 'spfx-app-dev'
const arr = ['theme', { active: true, item: false }]; cssClasses('spfx-app-dev', arr);  // => 'spfx-app-dev theme active'

getDeepOrDefault

since @spfxappdev/utility@1.0.0

Gets a nested property from an specific object or default, if not isset.

Examples
import { getDeepOrDefault } from '@spfxappdev/utility';

//VARIABLES
const simpleArray: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 }
];

const myObj = {
    My: {
        nested: {
            property: "Hello from nested Property"
        }
    },
    items: simpleArray
};
//VARIABLES END

// try get myObj.My.nested.property
getDeepOrDefault(myObj, "My.nested.property"); //=> "Hello from nested Property"

//ARRAY
getDeepOrDefault(myObj, "items.2") //=> { id: "tA2en", name: "Dev", sequence: 3 }

//TypeSafe
const arr: ISimpleItem[] = getDeepOrDefault<ISimpleItem[]>(myObj, "items");
console.log(arr[0].name);

//Default value
getDeepOrDefault(myObj, "404", "this string is returend as default, because 404 does not exist in myObj")

getUrlParameter

since @spfxappdev/utility@1.0.0

Get's the Value of a specific Url-Parameter

Examples
import { getUrlParameter } from '@spfxappdev/utility';

getUrlParameter('myParam', 'https://spfx-app.dev?myParam=1'); // => '1'
getUrlParameter('myParam2', 'https://spfx-app.dev?myParam=1');  // => null
getUrlParameter('myParam2');  // => Using window.location.href as URL

isAnyNullOrEmpty

since @spfxappdev/utility@1.3.0

Determines if any of the the provided properties are null, undefined, or empty (or whitespace if string-value).

Examples
import { isAnyNullOrEmpty } from '@spfxappdev/utility';

const emptyArr = []; //EMPTY
const obj = {}; //NOT null, undefined or empty
const notEmptyString = 'not empty';
const emptyString = '      '; // With whitespace

isAnyNullOrEmpty(obj, notEmptyString); //false
isAnyNullOrEmpty(obj, emptyString); // true
isAnyNullOrEmpty(emptyArr, emptyString, obj, notEmptyString); // true

isAnySet

since @spfxappdev/utility@1.3.0

Determines if any of the the provided properties are set (not null or undefined).

Examples
import { isAnySet } from '@spfxappdev/utility';

const emptyArr = []; //EMPTY
const obj = {}; //NOT null, undefined or empty
const notEmptyString = 'not empty';
const emptyString = '      '; // With whitespace
let notSet;

isAnySet(obj) // true
isAnySet(emptyArr, emptyString); // true
isAnySet(obj, notEmptyString); //true
isAnySet(undefined, emptyString); // true
isAnySet(obj, null, notSet); // true
isAnySet(notSet, undefined, null); //false

isFunction

since @spfxappdev/utility@1.0.0

Determines wheter the property is a Function.

Examples
import { isFunction } from '@spfxappdev/utility';

const myObj = { a: { nestedA: { nestedNestedA: 'a' }}};
const myFunc = () => { return a};
isFunction(myObj); // => false
isFunction(myFunc); // => true
isFunction(undefined) // => false

isNullOrEmpty

since @spfxappdev/utility@1.0.0

Determines if the provided property is null or empty (or whitespace if string-value).

Examples
import { isNullOrEmpty } from '@spfxappdev/utility';

isNullOrEmpty("this is a string") // ==>  false
isNullOrEmpty(1) // ==>  false
isNullOrEmpty(() => { }) // ==>  true
isNullOrEmpty(null) // ==>  true
isNullOrEmpty(undefined) // ==>  true
isNullOrEmpty([]) // ==>  true
isNullOrEmpty([1,2]) // ==>  false
isNullOrEmpty({}) // ==>  false
isNullOrEmpty("") // ==>  true
isNullOrEmpty("     ") // ==>  true

isset

since @spfxappdev/utility@1.0.0

Determines if the provided property is set.

Examples
import { isset } from '@spfxappdev/utility';

isset("this is a string") // ==>  true
isset(1) // ==>  true
isset(() => { }) // ==>  true
isset(null) // ==>  false
isset(undefined) // ==>  false
isset([]) // ==>  true
isset([1,2]) // ==>  true
isset({}) // ==>  true
isset("") // ==>  true
isset("     ") // ==>  true

issetDeep

since @spfxappdev/utility@1.0.0

Determines if the provided property is set deep/nested

Examples
import { issetDeep } from '@spfxappdev/utility';

const myObj = {
    My: {
        nested: {
            property: "Hello from nested Property"
        }
    },
    items: [1,2,3,4]
};

issetDeep(myObj, "My.nested.property"); // ==> true

issetDeep(myObj, "items.2"); // ==> true

issetDeep(myObj, "404"); // ==> false

isValidEmail

since @spfxappdev/utility@1.1.0

Checks if the passed value is a valid email

Examples
import { isValidEmail } from '@spfxappdev/utility';
isValidEmail('[email protected]'); // ==> true
isValidEmail('spfx-app.dev'); // ==> false
isValidEmail('[email protected]'); // ==> false
isValidEmail('[email protected]'); // ==> false
isValidEmail('[email protected]'); // ==> true

promiseQueue

since @spfxappdev/utility@1.1.0

Executes a list of Promise one after one (in a queu). An Error/reject will not stop the next promise call.

Examples
import { promiseQueue, PromiseQueue, toParameterlessPromiseQueueFunc } from '@spfxappdev/utility';
const promise1 = toParameterlessPromiseQueueFunc(this.dummyPromise, true, 10000);
const promise2 = this.parameterlessPromiseFunc;
const promise3 = toParameterlessPromiseQueueFunc(this.dummyPromise, false, 2000);
const promise4 = toParameterlessPromiseQueueFunc(this.dummyPromise, true, 600);

await promiseQueue([promise1, promise2, promise3, promise4], 0);

//OR (with callback and error-handling)

const promises: Array<PromiseQueue<any>> = [ 
    { promiseFunc: promise1, callback: onSuccessFunc, onError: onErrorFunc}, 
    { promiseFunc: promise2, callback: onSuccessFuncPromise, onError: onErrorFunc}, 
    { promiseFunc: promise3, callback: onSuccessFunc, onError: onErrorFuncPromise}, 
    { promiseFunc: promise4, callback: onSuccessFunc, onError: onErrorFunc} 
];

await promiseQueue(promises, 0)

randomString

since @spfxappdev/utility@1.1.0

Generates a new and random string

Examples
import { randomString } from '@spfxappdev/utility';
randomString(); // ==> tA2en
randomString(15); // ==> G4XBtQcgDSHWdQG
randomString(6, 'abcdef0123456789'); // ==> fe693c ==> random hex color

removeAllParametersFromUrl

since @spfxappdev/utility@1.2.0

Removes all URL parameters and URL-Fragments (hash) from the passed url

Examples
import { removeAllParametersFromUrl } from '@spfxappdev/utility';
removeAllParametersFromUrl("https://spfx-app.dev#firstAnchor#secondAnchor"); // ==> https://spfx-app.dev
removeAllParametersFromUrl("https://spfx-app.dev/path1/path2?param1=1&param2=2#firstAnchor#secondAnchor"); // ==> https://spfx-app.dev/path1/path2
removeAllParametersFromUrl("https://spfx-app.dev/#/routedpath"); // ==> https://spfx-app.dev/

replaceNonAlphanumeric

since @spfxappdev/utility@1.1.0

Replaces all non-alphanumeric characters (incl. underscores) with the passed value

Examples
import { randomString } from '@spfxappdev/utility';
replaceNonAlphanumeric('This is a text: 1234567890ß!"§$%&/()=?+#____<---->'); // ==> Thisisatext1234567890____
replaceNonAlphanumeric('This is a text: öäü1234567890ß!"§$%&/()=?+#____<---->', '*') // ==> This*is*a*text*****1234567890**************____******

replaceTpl

since @spfxappdev/utility@1.2.0

Replaces all occurrences of the placeholder in the specified template

Examples
import { replaceTpl } from '@spfxappdev/utility';
replaceTpl("Hello {UserName}. Welcome {UserName}, this placeholder is not available: {SPFxAppDev}", { UserName: "SPFxAppDev" }); 
// Result: Hello SPFxAppDev. Welcome SPFxAppDev, this placeholder is not available: {SPFxAppDev}

//With functions
replaceTpl("Hello {User.FirstName} {User.LastName}, last login: {User.LastLogin}", { User: { FirstName: "SPFxApp", LastName: "Dev", LastLogin: () => { return new Date().toString(); } } });
// Result: Hello SPFxApp Dev, last login: Tue Nov 15 2022 15:59:34 GMT+0100 (Central European Standard Time)

replaceTpl("Hello {404}", { User: { FirstName: "SPFxApp", LastName: "Dev" } }, "");
// Result: Hello 

stripHTML

since @spfxappdev/utility@1.1.0

Strips the HTML and returns only the text content

Examples
import { stripHTML } from '@spfxappdev/utility';
stripHTML(`<div class='abc'>Hello <strong>spfxappdev</strong></div>)`) // ==> Hello spfxappdev
stripHTML('Hello spfxappdev'); // ==> Hello spfxappdev

toBoolean

since @spfxappdev/utility@1.0.0

Converts a value to a boolean

Examples
import { toBoolean } from '@spfxappdev/utility';
toBoolean(''); // => false
toBoolean('1'); // => true
toBoolean('42'); // => false
toBoolean(1); // => true
toBoolean(0); // => false
toBoolean(true); // => true
toBoolean(false); // => false
toBoolean(undefined) // => false

Date functions

countWorkdays

since @spfxappdev/utility@1.2.0

Counts all working days from a given date to another date. You can pass an array with dates that should not be counted (e.g. holidays).

Examples
//Current date (new Date()) ==> is 14 November
countWorkdays(); //workdays in November 2022, Monday-Friday ==> 22
countWorkdays(new Date(2022, 10, 14)); //workdays from 14th November 2022 until end of month, Monday-Friday ==> 13
countWorkdays(new Date(2022, 10, 14), new Date(2022, 10, 20)); //workdays from 14th November 2022 until 20th Nov 2022, Monday-Friday ==> 5
countWorkdays(undefined, undefined, 1, Weekday.Saturday); //workdays in November 2022, Monday-Saturday ==> 26
countWorkdays(new Date(2022, 11, 1), undefined, undefined, undefined, [new Date(2022, 11, 24), new Date(2022, 11, 25), new Date(2022, 11, 26), new Date(2022, 11, 31)]); //workdays in December 2022, Monday-Friday and day off (24-26th + 31st) ==> 21

firstDayOfMonth

since @spfxappdev/utility@1.2.0

Determines the first day of month of the current or specified date.

Examples
//Current date (new Date()) ==> is 14 November
firstDayOfMonth(); //Tue Nov 01 2022
firstDayOfMonth(new Date(2022, 1, 15)); //Tue Feb 01 2022

firstDayOfWeek

since @spfxappdev/utility@1.2.0

Determines the first day of week of the current or specified date.

Examples
//Current date (new Date()) ==> is 14 November
firstDayOfWeek()); //Mon Nov 14 2022
firstDayOfWeek(new Date(2022, 1, 15))); //Mon Feb 14 2022
//THE WEEK BEGINS WITH SUNDAY
firstDayOfWeek(null, Weekday.Sunday)); //Sun Nov 13 2022

formatDate

since @spfxappdev/utility@1.2.0

Simple conversion of a date object to a specified string format.

Examples
//Current date (new Date()) ==> is 14 November
formatDate("dd.MM.yyyy")); //Now ==> 14.11.2022
formatDate("MM/dd/yyyy", new Date(2022, 1, 1))); //result: 02/01/2022
formatDate("M/d/yy", new Date(2022, 1, 1))); //result: 2/1/22

Possible values in format could be:

| Input | Example | Description | |-------|---------|-------------------------------------| | yyyy | 2022 | 4 digit year | | yy | 22 | 2 digit year | | MM | 09 | 2 digit month number | | M | 9 or 11 | 1-2 digit month number | | dd | 09 | 2 digit day of month number | | d | 9 or 11 | 1-2 digit day of month number | | HH | 09 | 2 digit hours number (24h format) | | H | 9 or 11 | 1-2 digit hours number (24h format) | | mm | 09 | 2 digit minutes number | | m | 9 or 11 | 1-2 digit minutes number | | ss | 09 | 2 digit seconds number | | s | 9 or 11 | 1-2 digit seconds number |


lastDayOfMonth

since @spfxappdev/utility@1.2.0

Determines the last day of month of the current or specified date.

Examples
//Current date (new Date()) ==> is 14 November
lastDayOfMonth(); //Wed Nov 30 2022
lastDayOfMonth(new Date(2022, 1, 15)); //Mon Feb 28 2022

lastDayOfWeek

since @spfxappdev/utility@1.2.0

Determines the last day of week of the current or specified date.

Examples
//Current date (new Date()) ==> is 14 November
lastDayOfWeek()); //Sun Nov 20 2022
lastDayOfWeek(new Date(2022, 1, 15))); //Sun Feb 20 2022
//THE WEEK BEGINS WITH SUNDAY
lastDayOfWeek(null, Weekday.Sunday)); //Sat Nov 19 2022

weekNumber

since @spfxappdev/utility@1.2.0

Determines the week number of the current or specified date (ISO 8601 = the week with the starting year's first Thursday in it).

Examples
//Current date (new Date()) ==> is 14 November
weekNumber(); //2022 Nov 14 ==> 46
weekNumber(new Date(2022, 1, 15)); //2022 Feb 15 ==> 7
weekNumber(new Date(2019, 11, 30)); //2019 Dec 30 (special case) ==> 1

String-Extensions

The String Extensions extend the String Prototype. So you can use the following methods directly on a string variable.

Note: The variable must not be undefined or null. Otherwise an exception is thrown (see example below).
let undefinedString: string;
undefinedString.StartsWith("error"); //Throws an error, because the variable is not defined.

Usage

  1. import the extensions
import '@spfxappdev/utility/lib/extensions/StringExtensions';

API

Contains

since @spfxappdev/utility@1.0.0

Returns a value indicating whether a specified substring occurs within this string.

Examples
"Hello @spfxappdev/utility".Contains('@SPFxAppDev/Utility'); // ==>  true (ignore case)
"Hello @spfxappdev/utility".Contains('@SPFxAppDev/Utility', false); // ==>  false
"Hello @spfxappdev/utility".Contains('404'); // ==>  false

EndsWith

since @spfxappdev/utility@1.0.0

Determines whether the ending of a string instance matches a specified string.

Examples
"Hello @spfxappdev/utility".EndsWith('@SPFxAppDev/Utility'); // ==>  true (ignore case)
"Hello @spfxappdev/utility".EndsWith('@SPFxAppDev/Utility', false); // ==>  false
"Hello @spfxappdev/utility".EndsWith('@spfxappdev'); // ==>  false

Equals

since @spfxappdev/utility@1.0.0

Determines whether two String objects have the same value.

Examples
"Hello @spfxappdev/utility".Equals('HeLlO @SPFxAppDev/UTILITY'); // ==>  true (ignore case)
"Hello @spfxappdev/utility".Equals('HeLlO @SPFxAppDev/UTILITY', false); // ==>  false
"Hello @spfxappdev/utility".Equals('404'); // ==>  false

IndexOf

since @spfxappdev/utility@1.0.0

Reports the zero-based index of the first occurrence of a specified Unicode character or string within this instance. The method returns -1 if the character or string is not found in this instance.

Examples
"Hello @spfxappdev/utility".IndexOf('@SPFxAppDev/Utility'); // ==>  6 (ignore case)
"Hello @spfxappdev/utility".IndexOf('@SPFxAppDev/Utility', false); // ==>  -1
"Hello @spfxappdev/utility".IndexOf('404'); // ==>  -1

Insert

since @spfxappdev/utility@1.0.0

Returns a new string in which a specified string is inserted at a specified index position in this instance.

Examples
"Hello @spfxappdev/utility".Insert(5, " from"); // ==>  Hello from @spfxappdev/utility
"Hello @spfxappdev/utility".Insert(255, " insert to end"); // ==>  Hello @spfxappdev/utility insert to end

IsEmpty

since @spfxappdev/utility@1.0.0

Determines whether a String is empty or whitespace.

Examples
"Hello @spfxappdev/utility".IsEmpty()); // ==>  false
"".IsEmpty(); // ==> true
"     ".IsEmpty(); // ==> true

ReplaceAll

since @spfxappdev/utility@1.2.0

Replaces all occurrences of searchTerm with replaceWith

Examples
"Helloo Woorld, welcoome too string extensioons".ReplaceAll("oo", "o"); // ==>  Hello World, welcome to string extensions

StartsWith

since @spfxappdev/utility@1.0.0

Determines whether the beginning of this string instance matches a specified string.

Examples
"Hello @spfxappdev/utility".StartsWith('hello'); // ==>  true (ignore case)
"Hello @spfxappdev/utility".StartsWith('hello', false); // ==>  false
"Hello @spfxappdev/utility".StartsWith('@spfxappdev'); // ==>  false

Array-Extensions

Note: The variable must not be undefined or null. Otherwise an exception is thrown (see example below).
let undefinedArr: string[];
undefinedArr.Contains("error"); //Throws an error, because the variable is not defined.

Usage

  1. import the extensions
import '@spfxappdev/utility/lib/extensions/ArrayExtensions';

API

AddAt

since @spfxappdev/utility@1.1.0

Add one or more items at specified index.

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 }
];


myArr.AddAt(0, { id: randomString(), name: "First Item", sequence: 0 });
myArr.AddAt(1, { id: randomString(), name: "Second Item", sequence: 1 });
myArr.AddAt(1000, { id: randomString(), name: "LAST Item", sequence: 10000 });
myArr.AddAt(-3, { id: randomString(), name: "LAST Item - 3", sequence: 10000 });

//Result:
myArr = [
{"id":"Vb9Lq","name":"First Item","sequence":0},
{"id":"aCrdT","name":"Second Item","sequence":1},
{"id":"bjdvY","name":"App","sequence":2},
{"id":"fb80g","name":"LAST Item - 3","sequence":10000},
{"id":"g4JQl","name":"SPFx","sequence":1},
{"id":"oYHgy","name":"Dev","sequence":3},
{"id":"XYcxD","name":"LAST Item","sequence":10000}
];

Contains

since @spfxappdev/utility@1.1.0

Determines whether an array contains a particular element that satisfies the condition

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 }
];


const containsSpfxItem: boolean = myArr.Contains(i => i.name.Equals("spfx"));

console.log(containsSpfxItem); //true

const contains404Item: boolean = myArr.Contains(i => i.name.Equals("404"));

console.log(contains404Item); //false

const multipleConditions: boolean = myArr.Contains(i => i.name.Equals("404") || i.name.Equals("spfx"));

console.log(multipleConditions); // true

const emptyArrayContains: boolean = [].Contains(i => (i as any).name.Equals("404") || (i as any).name.Equals("spfx"));

console.log(emptyArrayContains); //false

Count

since @spfxappdev/utility@1.1.0

Determines whether an array contains a particular element that satisfies the condition

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 },
    { id: randomString(), name: "App", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 5 }
];


const totalAppItems: number = myArr.Count(i => i.name.Equals("app"));

console.log(totalAppItems); //==> 2


const total404Items: number = myArr.Count(i => i.name.Equals("404"));

console.log(total404Items); // ==> 0

const totalAppOrDevItems: number = myArr.Count(i => i.name.Equals("app") || i.name.Equals("dEv"));

console.log(totalAppOrDevItems); // ==> 5

const emptyArrayCount: number = [].Count(i => (i as any).name.Equals("404") || (i as any).name.Equals("spfx"));

console.log(emptyArrayCount); // ==> 0

FirstOrDefault

since @spfxappdev/utility@1.0.0

Returns the first element of a the array, or the first element that satisfies the condition (by predicateFunc), or defaultValue if no element is found.

Note: Since v1.1.0 the predicateFunc is optional. If not specified the first element (index == 0) will be returned or defaultValue
Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 },
    { id: randomString(), name: "App", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 5 }
];


const spfxItem: ISimpleItem|null = myArr.FirstOrDefault(i => i.name.Equals("spfx"));

console.log(spfxItem); // ==> { id: "g4JQl", name: "SPFx", sequence: 1 }

const firstItem: ISimpleItem|null = myArr.FirstOrDefault();

console.log(firstItem); // ==> { id: "bjdvY", name: "App", sequence: 2 }

const defaultItem: ISimpleItem|null = myArr.FirstOrDefault(i => i.name.Equals("404"), { id: randomString(), name: "This is item is the default item, because the searched item was not found", sequence: 404 });

console.log(defaultItem); // ==> { id: "6xcPO", name: "This is item is the default item, because the searched item was not found", sequence: 404 }

const defaultNullItem: ISimpleItem|null = myArr.FirstOrDefault(i => i.name.Equals("404"));

console.log(defaultNullItem); // ==> null

IndexOf

since @spfxappdev/utility@1.0.0

Returns the first index of element of a sequence, or -1 if no element is found.

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 },
    { id: randomString(), name: "App", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 5 }
];


const spfxItemIndex: number = myArr.IndexOf(i => i.name.Equals("spfx"));

console.log(spfxItemIndex); // ==> 1


const notFoundIndex: number = myArr.IndexOf(i => i.name.Equals("404"));

console.log(notFoundIndex); // ==> -1

LastOrDefault

since @spfxappdev/utility@1.1.0

Returns the last element of a the array, or the last element that satisfies the condition (by predicateFunc), or defaultValue if no element is found.

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 },
    { id: randomString(), name: "SPFx", sequence: 4 },
    { id: randomString(), name: "SPFx", sequence: 5 },
    { id: randomString(), name: "SPFx", sequence: 6 },
    { id: randomString(), name: "Dev", sequence: 1000 }
];


const spfxItem: ISimpleItem|null = myArr.LastOrDefault(i => i.name.Equals("spfx"));

console.log(spfxItem); // ==> {id: 't9Rhm', name: 'SPFx', sequence: 6}

const lastItem: ISimpleItem|null = myArr.LastOrDefault();

console.log(lastItem); // ==> {id: 'Uqyvt', name: 'Dev', sequence: 1000}

const defaultItem: ISimpleItem|null = myArr.LastOrDefault(i => i.name.Equals("404"), { id: randomString(), name: "This is item is the default item, because the searched item was not found", sequence: 404 });

console.log(defaultItem); // ==> {id: 'L3g64', name: 'This is item is the default item, because the searched item was not found', sequence: 404}

const defaultNullItem: ISimpleItem|null = myArr.LastOrDefault(i => i.name.Equals("404"));

console.log(defaultNullItem); // ==> null

const emptyArrCheck: ISimpleItem|null = [].LastOrDefault(i => (i as any).name.Equals("404"));

console.log(emptyArrCheck); // ==> null

OrderBy

since @spfxappdev/utility@1.0.0

Sorts the elements of a sequence in ascending order.

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 }
];


myArr.OrderBy(i => i.sequence);

console.log(myArr); // ==> [{id: 'g4JQl', name: 'SPFx', sequence: 1},{id: 'bjdvY', name: 'App', sequence: 2},{id: 'oYHgy', name: 'Dev', sequence: 3}]

myArr.OrderBy(i => i.name);

console.log(myArr); // ==> [{id: 'bjdvY', name: 'App', sequence: 2},,{id: 'oYHgy', name: 'Dev', sequence: 3},{id: 'g4JQl', name: 'SPFx', sequence: 1}]

OrderByDescending

since @spfxappdev/utility@1.0.0

Sorts the elements of a sequence in descending order.

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 }
];


myArr.OrderByDescending(i => i.sequence);

console.log(myArr); // ==> [{id: 'oYHgy', name: 'Dev', sequence: 3},{id: 'bjdvY', name: 'App', sequence: 2},{id: 'g4JQl', name: 'SPFx', sequence: 1}]

myArr.OrderByDescending(i => i.name);

console.log(myArr); // ==> [{id: 'g4JQl', name: 'SPFx', sequence: 1},{id: 'oYHgy', name: 'Dev', sequence: 3},{id: 'bjdvY', name: 'App', sequence: 2}]

OrderByMultiple

since @spfxappdev/utility@1.0.0

Sorts the elements of a sequence in ascending order (first by a then by b then by c etc.).

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 },
    { id: randomString(), name: "App", sequence: 1 }
];


myArr.OrderByMultiple([(item) => item.name, (item) => item.sequence]);

console.log(myArr); // ==> [{id: 'EceZ9', name: 'App', sequence: 1},{id: 'bjdvY', name: 'App', sequence: 2},{id: 'oYHgy', name: 'Dev', sequence: 3},{id: 'g4JQl', name: 'SPFx', sequence: 1}]

OrderByMultipleDescending

since @spfxappdev/utility@1.0.0

Sorts the elements of a sequence in descending order (first by a then by b then by c etc.)

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 },
    { id: randomString(), name: "App", sequence: 1 }
];


myArr.OrderByMultipleDescending([(item) => item.name, (item) => item.sequence]);

console.log(myArr); // ==> [{id: 'g4JQl', name: 'SPFx', sequence: 1},{id: 'oYHgy', name: 'Dev', sequence: 3},{id: 'bjdvY', name: 'App', sequence: 2},{id: 'Kp45S', name: 'App', sequence: 1}]

RemoveAt

since @spfxappdev/utility@1.1.0

Remove the item(s) at specified index

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "First Item", sequence: 0 },
    { id: randomString(), name: "Second Item", sequence: 1 },
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: 'LAST Item - 3', sequence: 10000},
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 },
    { id: randomString(), name: "App", sequence: 1 },
    { id: randomString(), name: "LAST Item", sequence: 10000 }
];


//Remove 2 items, starting at index 0
myArr.RemoveAt(0, 2);

console.log(myArr); // ==> [{id: 'bjdvY', name: 'App', sequence: 2},{id: 'feIpa', name: 'LAST Item - 3', sequence: 10000},{id: 'g4JQl', name: 'SPFx', sequence: 1},{id: 'oYHgy', name: 'Dev', sequence: 3},{id: '7yL7k', name: 'LAST Item', sequence: 10000}]

//remove the item at index 2
myArr.RemoveAt(2);

console.log(myArr); // ==> [{id: 'bjdvY', name: 'App', sequence: 2},{id: 'feIpa', name: 'LAST Item - 3', sequence: 10000},{id: 'oYHgy', name: 'Dev', sequence: 3},{id: '7yL7k', name: 'LAST Item', sequence: 10000}]

myArr.RemoveAt(-3);

console.log(myArr); // ==> [{id: 'bjdvY', name: 'App', sequence: 2},{id: 'oYHgy', name: 'Dev', sequence: 3},{id: '7yL7k', name: 'LAST Item', sequence: 10000}]

Where

since @spfxappdev/utility@1.0.0

Filters a sequence of values based on a predicate.

Examples

const myArr: ISimpleItem[] = [
    { id: randomString(), name: "App", sequence: 2 },
    { id: randomString(), name: "SPFx", sequence: 1 },
    { id: randomString(), name: "Dev", sequence: 3 },
];


const allItemsWhereSequenceGt1: ISimpleItem[] = myArr.Where(i => i.sequence > 1);

console.log(allItemsWhereSequenceGt1); //==> [{ id: 'bjdvY', name: "App", sequence: 2 },{id: 'oYHgy', name: 'Dev', sequence: 3}]


const notFoundItems: ISimpleItem[] = myArr.Where(i => i.name.Equals("404"));

console.log(notFoundItems); // ==> []

Decorators

The decorators are helpful if you want to achieve a lot with less code and also fast.

In order to better understand how decorators work, I recommend reading this article.

Simple definition: An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an @ character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class, a method or a property.

Let's compare the same code without decorators and with decorators (by using the tryCatch decorator). The logic is not changed, but the result is the same:

Simple class WITHOUT decorators

class MyExampleClass {

    public dummyFunc(str: string): number {
        try {
            //will throw an error, if str is undefined;
           return str.indexOf("h");
        }
        catch(error) {
            //do something
        }

        return 0;
    }
}

(Same) Simple class WITH decorators

class MyExampleClass {
    
    @tryCatch<number>({
        defaultValueOnError: 0
    })
    public dummyFunc(str: string): number {
        return str.indexOf("h");
    }
}

Needless to say, decorators save a lot of time, reduce the number of lines (13 lines vs. 8 lines) and improve readability.

How to use decorators


INFO: To use the method decorators, you must set the experimentalDecorators property in your tsconfig.json to true.

Here is a list of all available method decorators:

| Decorator name | Description | |---------------------------------------|------------------------------------| | @tryCatch | Decorator to wrap a class method with a try-catch block. Works also with Promise |

In order to use the decorators, they must be imported

export { tryCatch  } from '@spfxappdev/storage';

@tryCatch

since @spfxappdev/utility@1.4.0

Decorator to wrap a class method with a try-catch block. Works also with Promise

Example
class MyExampleClass {
    
    @tryCatch<number>({
        defaultValueOnError: 0
    })
    public dummyFunc(str: string): number {
        return str.indexOf("h");
    }
}