# json-query

> Retrieves values from JSON objects for data binding. Offers params, nested queries, deep queries, custom reduce/filter functions and simple boolean logic. Browserify compatible.

Latest version **2.2.2** (published 2017-04-05) · 0 weekly downloads

## Install

```sh
npm install json-query
pnpm add json-query
yarn add json-query
bun add json-query
```

## Health

**Score 23/100 (F)** — status: abandoned.

Positive: has types package; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.2.2 |
| Published | 2017-04-05 |
| First published | 2013-01-18 |
| Weekly downloads | 0 |
| TypeScript types | separate (@types/json-query) |
| Module format | CommonJS |
| Node | * |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Matt McKegg |
| Maintainers | mmckegg |
| Keywords | data binding, filter, json, query |

## Links

- npm: https://www.npmjs.com/package/json-query
- Repository: https://github.com/mmckegg/json-query
- Homepage: http://github.com/mmckegg/json-query
- Issues: https://github.com/mmckegg/json-query/issues
- npm.io page: https://npm.io/package/json-query

## Alternatives

- [@mapbox/jsonlint-lines-primitives](https://npm.io/package/@mapbox/jsonlint-lines-primitives.md) — 5.3M weekly downloads
- [reftools](https://npm.io/package/reftools.md) — 3.5M weekly downloads
- [@hey-api/openapi-ts](https://npm.io/package/@hey-api/openapi-ts.md) — 3.5M weekly downloads
- [@mapbox/geojson-rewind](https://npm.io/package/@mapbox/geojson-rewind.md) — 2.4M weekly downloads
- [turbo-stream](https://npm.io/package/turbo-stream.md) — 1.7M weekly downloads

## Recent versions

- 2.2.2 (latest) — 2017-04-05
- 2.2.1 — 2017-04-05
- 2.2.0 — 2016-09-05
- 2.1.1 — 2016-07-18
- 2.1.0 — 2016-05-27
- 2.0.2 — 2016-05-24
- 2.0.1 — 2016-05-22
- 2.0.0 — 2016-05-22
- 1.8.0 — 2016-03-02
- 1.7.0 — 2016-02-28
- 1.6.0 — 2016-02-15
- 1.5.0 — 2015-04-27
- 1.4.0 — 2014-10-15
- 1.3.1 — 2014-10-13
- 1.3.0 — 2014-10-08
- … 16 more at https://npm.io/package/json-query/versions

## README

json-query
===

Retrieves values from JSON objects for data binding. Offers params, nested queries, deep queries, custom reduce/filter functions and simple boolean logic.

## Install via [npm](https://www.npmjs.com/package/json-query)

```bash
$ npm install json-query
```

## API

```js
var jsonQuery = require('json-query')
```

### `jsonQuery(query, options)`

Specify a query and what to query. Returns an object that describes the result of the query.

```js

var data = {
  people: [
    {name: 'Matt', country: 'NZ'},
    {name: 'Pete', country: 'AU'},
    {name: 'Mikey', country: 'NZ'}
  ]
}

jsonQuery('people[country=NZ].name', {
  data: data
}) //=> {value: 'Matt', parents: [...], key: 0} ... etc
```

#### Options:

- **`data`** or **`rootContext`**: The main object to query.
- **`source`** or **`context`** (optional): The current object we're interested in. Accessed in query with `.`.
- **`parent`** (optional): An additional context for looking further up the tree. Accessed by `..`.
- **`locals`**: Specify an object containing helper functions. Accessed by `':filterName'`. Expects `function(input, args...)` with `this` set to original passed in options.
- **`globals`**: Falls back to globals when no local function found.
- **`force`** (optional): Specify an object to be returned from the query if the query fails. It will be saved into the place the query expected the object to be.
- **`allowRegexp`** (optional): Enable the `~` operator. Before enabling regexp match to anyone, consider the [user defined regular expression security concerns](http://stackoverflow.com/questions/20928677/user-defined-regular-expression-security-concerns).

## Queries

Queries are strings that describe an object or value to pluck out, or manipulate from the context object. The syntax is a little bit CSS, a little bit JS, but pretty powerful.

### Accessing properties (dot notation)

`person.name`

### Array accessors

`people[0]`

### Array pluck

`people.name` => return all the names of people

### Get all values of a lookup

`lookup[*]`

### Array filter

By default **only the first** matching item will be returned:

`people[name=Matt]`

But if you add an asterisk (`*`), **all** matching items will be returned:

`people[*country=NZ]`

You can use comparative operators:

`people[*rating>=3]`

Or use boolean logic:

`people[* rating >= 3 & starred = true]`

If `options.enableRegexp` is enabled, you can use the `~` operator to match `RegExp`:

`people[*name~/^R/i]`

You can also **negate** any of the above examples by adding a `!` before the `=` or `~`:

`people[*country!=NZ]`

### Or syntax

`person.greetingName|person.name`

### Deep queries

Search through multiple levels of Objects/Arrays using `[**]`:

```js
var data = {
  grouped_people: {
    'friends': [
      {name: 'Steve', country: 'NZ'},
      {name: 'Jane', country: 'US'},
      {name: 'Mike', country: 'AU'},
      {name: 'Mary', country: 'NZ'},
    ],
    'enemies': [
      {name: 'Evil Steve', country: 'AU'}
      {name: 'Betty', country: 'NZ'},
    ]
  }
}

var result = jsonQuery('grouped_people[**][*country=NZ]', {data: data}).value
```

The `result` will be:

```js
[
  {name: 'Steve', country: 'NZ'},
  {name: 'Mary', country: 'NZ'},
  {name: 'Betty', country: 'NZ'}
]
```

### Inner queries

```js
var data = {
  page: {
    id: 'page_1',
    title: 'Test'
  },
  comments_lookup: {
    'page_1': [
      {id: 'comment_1', parent_id: 'page_1', content: "I am a comment"}
    ]
  }
}

// get the comments that match page's id
jsonQuery('comments_lookup[{page.id}]', {data: data})
```

### Local functions (helpers)

Allows you to hack the query system to do just about anything.

Some nicely contrived examples:

```js
var helpers = {
  greetingName: function(input){
    if (input.known_as){
      return input.known_as
    } else {
      return input.name
    }
  },
  and: function(inputA, inputB){
    return inputA && inputB
  },
  text: function(input, text){
    return text
  },
  then: function(input, thenValue, elseValue){
    if (input){
      return thenValue
    } else {
      return elseValue
    }
  }
}

var data = {
  is_fullscreen: true,
  is_playing: false,
  user: {
    name: "Matthew McKegg",
    known_as: "Matt"
  }
}

jsonQuery('user:greetingName', {
  data: data, locals: helpers
}).value //=> "Matt"

jsonQuery(['is_fullscreen:and({is_playing}):then(?, ?)', "Playing big!", "Not so much"], {
  data: data, locals: helpers
}).value //=> "Not so much"

jsonQuery(':text(This displays text cos we made it so)', {
  locals: helpers
}).value //=> "This displays text cos we made it so"

```

Or you could add a `select` helper:

```js
jsonQuery('people:select(name, country)', {
  data: data,
  locals: {
    select: function (input) {
      if (Array.isArray(input)) {
        var keys = [].slice.call(arguments, 1)
        return input.map(function (item) {
          return Object.keys(item).reduce(function (result, key) {
            if (~keys.indexOf(key)) {
              result[key] = item[key]
            }
            return result
          }, {})
        })
      }
    }
  }
})
```

You can also use helper functions inside array filtering:

```js
jsonQuery('people[*:recentlyUpdated]', {
  data: data,
  locals: {
    recentlyUpdated: function (item) {
      return item.updatedAt < Date.now() - (30 * 24 * 60 * 60 * 1000)
    }
  }
})
```

### Context

Specifying context (`data`, `source`, and `parent` options) is good for databinding and working on a specific object and still keeping the big picture available.

```js
var data = {
  styles: {
    bold: 'font-weight:strong',
    red: 'color: red'
  },
  paragraphs: [
    {content: "I am a red paragraph", style: 'red'},
    {content: "I am a bold paragraph", style: 'bold'},
  ],
}

var pageHtml = ''
data.paragraphs.forEach(function(paragraph){
  var style = jsonQuery('styles[{.style}]', {data: data, source: paragraph}).value
  var content = jsonQuery('.content', data: data, source: paragraph) // pretty pointless :)
  pageHtml += "<p style='" + style "'>" + content + "</p>"
})
```

## Query Params

Params can be specified by passing in an array with the first param the query (with `?` params) and subsequent params.

```js
jsonQuery(['people[country=?]', 'NZ'])
```

## License

MIT

---
_Source: https://npm.io/package/json-query · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
