diff --git a/docs/content/en/api/query-builder-methods.md b/docs/content/en/api/query-builder-methods.md index 1256e73..263f927 100644 --- a/docs/content/en/api/query-builder-methods.md +++ b/docs/content/en/api/query-builder-methods.md @@ -6,6 +6,7 @@ category: API --- ## `include` + - Arguments: `(...args)` - Returns: `self` @@ -26,6 +27,7 @@ await Model.include(['user', 'category']) `with` is an alias of this method. ## `append` + - Arguments: `(...args)` - Returns: `self` @@ -44,17 +46,20 @@ await Model.append(['likes', 'shares']) ``` ## `select` + - Arguments: `(...fields)` - Returns: `self` Set the columns to be selected. #### Single entity + ```js await Model.select(['title', 'content']) ``` #### Related entities + ```js await Post.select({ posts: ['title', 'content'], @@ -63,6 +68,7 @@ await Post.select({ ``` ## `where` + - Arguments: `(field, value)` - Returns: `self` @@ -89,6 +95,7 @@ await Model.where({ user: { status: 'active' } }) ``` ## `whereIn` + - Arguments: `(field, array)` - Returns: `self` @@ -115,13 +122,14 @@ await Model.where({ user: { id: [1, 2, 3] } }) ``` ## `orderBy` + - Arguments: `(...args)` - Returns: `self` Add an "order by" clause to the query. ```js -await Model.orderBy('-created_at', 'category_id') +await Model.orderBy('-created_at', 'category_id') ``` #### Array @@ -129,10 +137,11 @@ await Model.orderBy('-created_at', 'category_id') Available in version >= v1.8.0 ```js -await Model.orderBy(['-created_at', 'category_id']) +await Model.orderBy(['-created_at', 'category_id']) ``` ## `page` + - Arguments: `(value)` - Returns: `self` @@ -143,6 +152,7 @@ await Model.page(1) ``` ## `limit` + - Arguments: `(value)` - Returns: `self` @@ -153,6 +163,7 @@ await Model.limit(20) ``` ## `params` + - Arguments: `(payload)` - Returns: `self` @@ -161,24 +172,25 @@ Add custom parameters to the query. - ```js - await Model.params({ - foo: 'bar', - baz: true - }) - ``` +```js +await Model.params({ + foo: 'bar', + baz: true +}) +``` - ```http request - GET /resource?foo=bar&baz=true - ``` +```http request +GET /resource?foo=bar&baz=true +``` ## `when` + Available in version >= v1.10.0 - Arguments: `(value, callback)` @@ -192,7 +204,33 @@ const search = 'foo' await Model.when(search, (query, value) => query.where('search', value)) ``` +## `wrappedBy` + +Available in version >= v1.14.0 + +- Arguments: `(value)` +- Returns: `self` + +Change the `wrap()` data wrapper for this request. + +```js +await Model.wrappedBy('somewrapper').get() +``` + +## `nowrap` + +Available in version >= v1.14.0 + +- Returns: `self` + +Remove the `wrap()` data wrapper for this request to return the raw response. + +```js +await Model.nowrap().get() +``` + ## `custom` + - Arguments: `(...args)` - Returns: `self` @@ -201,38 +239,39 @@ Build custom endpoints. - ```js - await Post.custom('posts/latest') - ``` +```js +await Post.custom('posts/latest') +``` - ```http request - GET /posts/latest - ``` +```http request +GET /posts/latest +``` - ```js - const user = new User({ id: 1 }) - const post = new Post() +```js +const user = new User({ id: 1 }) +const post = new Post() - await Post.custom(user, post, 'latest') - ``` +await Post.custom(user, post, 'latest') +``` - ```http request - GET /users/1/posts/latest - ``` +```http request +GET /users/1/posts/latest +``` ## `config` + Available in version >= v1.8.0 - Arguments: `(config)` @@ -243,12 +282,15 @@ Configuration of HTTP Instance. ```js await Model.config({ method: 'PATCH', - header: { /* ... */ }, + header: { + /* ... */ + }, data: { foo: 'bar' } }).save() ``` ## `get` + - Returns: `Collection | { data: Collection }` Execute the query and get all results. @@ -260,6 +302,7 @@ await Model.get() `all` is an alias of this method. ## `first` + - Returns: `Model | { data: Model }` Execute the query and get the first result. @@ -269,6 +312,7 @@ await Model.first() ``` ## `find` + - Arguments: `(identifier)` - Returns: `Model | { data: Model }` @@ -279,6 +323,7 @@ await Model.find(1) ``` ## `$get` + - Returns: `Collection` Execute the query and get all results. @@ -293,6 +338,7 @@ They handle and unwrap responses within "data". `$all` is an alias of this method. ## `$first` + - Returns: `Model` Execute the query and get the first result. @@ -301,10 +347,11 @@ Execute the query and get the first result. await Model.$first() ``` -These `$`-prefixed convenience methods always return the requested content. +These `$`-prefixed convenience methods always return the requested content. They handle and unwrap responses within "data". ## `$find` + - Arguments: `(identifier)` - Returns: `Model` @@ -314,5 +361,5 @@ Find a model by its primary key. await Model.$find(1) ``` -These `$`-prefixed convenience methods always return the requested content. +These `$`-prefixed convenience methods always return the requested content. They handle and unwrap responses within "data". diff --git a/docs/content/en/configuration.md b/docs/content/en/configuration.md index 533cfaa..7c3724e 100644 --- a/docs/content/en/configuration.md +++ b/docs/content/en/configuration.md @@ -174,7 +174,7 @@ export default class Post extends Model { return 'posts' } - // Define the primary key of the model + // Define the response wrapper wrap() { return 'data' } diff --git a/src/Model.js b/src/Model.js index 113e7a0..f1eda56 100644 --- a/src/Model.js +++ b/src/Model.js @@ -12,6 +12,8 @@ export default class Model extends StaticModel { if (attributes.length === 0) { this._builder = new Builder(this) + // Set the default data wrapper + this._wrapper = this.wrap() } else { Object.assign(this, ...attributes) this._applyRelations(this) @@ -71,9 +73,8 @@ export default class Model extends StaticModel { * @return {object|array} The unwraped response */ _unwrap(response) { - const wrapper = this.wrap() - if (wrapper) { - return response[wrapper] || response + if (this._wrapper) { + return response[this._wrapper] || response } else { return response } @@ -285,6 +286,26 @@ export default class Model extends StaticModel { return this } + /** + * The "data" wrapper that will override the wrap() method + * + * @param {string} wrap The new wrapper for this one request + * + * @return {string|null} + */ + wrappedBy(wrap) { + this._wrapper = wrap + return this + } + + /** + * Disable wrapping for this one request + */ + nowrap() { + this._wrapper = null + return this + } + /** * Result */ diff --git a/src/StaticModel.js b/src/StaticModel.js index 61a25db..da2caec 100644 --- a/src/StaticModel.js +++ b/src/StaticModel.js @@ -88,6 +88,20 @@ export default class StaticModel { return self } + static wrappedBy(value) { + let self = this.instance() + self.wrappedBy(value) + + return self + } + + static nowrap() { + let self = this.instance() + self.nowrap() + + return self + } + static custom(...args) { let self = this.instance() self.custom(...args) diff --git a/tests/model.test.js b/tests/model.test.js index 5f66ab0..72e8198 100644 --- a/tests/model.test.js +++ b/tests/model.test.js @@ -334,6 +334,34 @@ describe('Model methods', () => { }) }) + test('nowrap().get() returns the full response with the "data" wrapper even though the wrap method is set', async () => { + // Set the wrap method to 'data' + Post.prototype['wrap'] = () => { + return 'data' + } + + axiosMock.onGet('http://localhost/posts').reply(200, postsEmbedResponse) + + const posts = await Post.nowrap().get() + + expect(posts).toEqual(postsEmbedResponse) + expect(posts.data[0]).toEqual(postsEmbedResponse.data[0]) + }) + + test('wrappedBy().get() returns the full response with the "data" wrapper even though the wrap method is set to `test`', async () => { + // Set the wrap method to 'data' + Post.prototype['wrap'] = () => { + return 'test' + } + + axiosMock.onGet('http://localhost/posts').reply(200, postsEmbedResponse) + + const posts = await Post.wrappedBy('data').get() + + expect(posts).toEqual(postsEmbedResponse.data) + expect(posts[0]).toEqual(postsEmbedResponse.data[0]) + }) + test('save() method makes a POST request when ID of object does not exists', async () => { let post const _postResponse = {