Moves vue resource docs into a new file.

Adds docs regarding handling 204 response
This commit is contained in:
Filipa Lacerda 2017-10-23 15:07:44 +03:00
parent 3f9022cf78
commit 008b6e8732
No known key found for this signature in database
GPG Key ID: 9CA3FDE4D1E2F1C8
3 changed files with 76 additions and 50 deletions

View File

@ -71,6 +71,9 @@ Vue specific design patterns and practices.
---
## [Vue Resource](vue_resource.md)
Vue resource specific practices and gotchas.
## [Icons](icons.md)
How we use SVG for our Icons.

View File

@ -179,6 +179,7 @@ itself, please read this guide: [State Management][state-management]
The Service is a class used only to communicate with the server.
It does not store or manipulate any data. It is not aware of the store or the components.
We use [vue-resource][vue-resource-repo] to communicate with the server.
Refer to [vue resource](vue_resource.md) for more details.
Vue Resource should only be imported in the service file.
@ -189,55 +190,6 @@ Vue Resource should only be imported in the service file.
Vue.use(VueResource);
```
#### Vue-resource gotchas
#### Headers
Headers are being parsed into a plain object in an interceptor.
In Vue-resource 1.x `headers` object was changed into an `Headers` object. In order to not change all old code, an interceptor was added.
If you need to write a unit test that takes the headers in consideration, you need to include an interceptor to parse the headers after your test interceptor.
You can see an example in `spec/javascripts/environments/environment_spec.js`:
```javascript
import { headersInterceptor } from './helpers/vue_resource_helper';
beforeEach(() => {
Vue.http.interceptors.push(myInterceptor);
Vue.http.interceptors.push(headersInterceptor);
});
afterEach(() => {
Vue.http.interceptors = _.without(Vue.http.interceptors, myInterceptor);
Vue.http.interceptors = _.without(Vue.http.interceptors, headersInterceptor);
});
```
#### `.json()`
When making a request to the server, you will most likely need to access the body of the response.
Use `.json()` to convert. Because `.json()` returns a Promise the follwoing structure should be used:
```javascript
service.get('url')
.then(resp => resp.json())
.then((data) => {
this.store.storeData(data);
})
.catch(() => new Flash('Something went wrong'));
```
When using `Poll` (`app/assets/javascripts/lib/utils/poll.js`), the `successCallback` needs to handle `.json()` as a Promise:
```javascript
successCallback: (response) => {
return response.json().then((data) => {
// handle the response
});
}
```
#### CSRF token
We use a Vue Resource interceptor to manage the CSRF token.
`app/assets/javascripts/vue_shared/vue_resource_interceptor.js` holds all our common interceptors.
Note: You don't need to load `app/assets/javascripts/vue_shared/vue_resource_interceptor.js`
since it's already being loaded by `common_vue.js`.
### End Result
The following example shows an application:
@ -769,7 +721,6 @@ describe('component', () => {
[component-system]: https://vuejs.org/v2/guide/#Composing-with-Components
[state-management]: https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch
[one-way-data-flow]: https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow
[vue-resource-repo]: https://github.com/pagekit/vue-resource
[vue-resource-interceptor]: https://github.com/pagekit/vue-resource/blob/develop/docs/http.md#interceptors
[vue-test]: https://vuejs.org/v2/guide/unit-testing.html
[issue-boards-service]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/boards/services/board_service.js.es6

View File

@ -0,0 +1,72 @@
# Vue Resouce
In Vue applications we use [vue-resource][vue-resource-repo] to communicate with the server.
## HTTP Status Codes
### `.json()`
When making a request to the server, you will most likely need to access the body of the response.
Use `.json()` to convert. Because `.json()` returns a Promise the follwoing structure should be used:
```javascript
service.get('url')
.then(resp => resp.json())
.then((data) => {
this.store.storeData(data);
})
.catch(() => new Flash('Something went wrong'));
```
When using `Poll` (`app/assets/javascripts/lib/utils/poll.js`), the `successCallback` needs to handle `.json()` as a Promise:
```javascript
successCallback: (response) => {
return response.json().then((data) => {
// handle the response
});
}
```
### 204
Some endpoints - usually `delete` endpoints - return `204` as the success response.
When handling `204 - No Content` responses, we cannot use `.json()` since it tries to parse the non-existant body content.
When handling `204` responses, do not use `.json`, otherwise the promise will throw an error and will enter the `catch` statement:
```javascript
Vue.http.delete('path')
.then(() => {
// success!
})
.catch(() => {
// handle error
})
```
## Headers
Headers are being parsed into a plain object in an interceptor.
In Vue-resource 1.x `headers` object was changed into an `Headers` object. In order to not change all old code, an interceptor was added.
If you need to write a unit test that takes the headers in consideration, you need to include an interceptor to parse the headers after your test interceptor.
You can see an example in `spec/javascripts/environments/environment_spec.js`:
```javascript
import { headersInterceptor } from './helpers/vue_resource_helper';
beforeEach(() => {
Vue.http.interceptors.push(myInterceptor);
Vue.http.interceptors.push(headersInterceptor);
});
afterEach(() => {
Vue.http.interceptors = _.without(Vue.http.interceptors, myInterceptor);
Vue.http.interceptors = _.without(Vue.http.interceptors, headersInterceptor);
});
```
## CSRF token
We use a Vue Resource interceptor to manage the CSRF token.
`app/assets/javascripts/vue_shared/vue_resource_interceptor.js` holds all our common interceptors.
Note: You don't need to load `app/assets/javascripts/vue_shared/vue_resource_interceptor.js`
since it's already being loaded by `common_vue.js`.
[vue-resource-repo]: https://github.com/pagekit/vue-resource