Use service object in nuxt.js

ihavecoke

mixbo

Posted on June 22, 2020

Use service object in nuxt.js

Alt Text

Nuxt.js awesome SSR framwork use in my team, we use axios lib to request http and deal with response.

Also we use Vuex to store state data between component and pages.

We just use service to wrap axios request, so that we can write logic more robust. let's show you some code

ApplicationService class

// ApplicationService.js

import extend from 'lodash/extend'
import { compact } from 'lodash'
import { environment } from '../config'

const querystring = require('querystring')

class ApplicationService {
  constructor(ctx) {
    this.cache = ctx.cache
    this.logger = ctx.app.$logger
    this.axios = ctx.$axios
  }
  get(path, params = {}, extraConf = {}) {
    return this.request(path, 'GET', params, extraConf)
  }

  post(path, data, extraConfig = {}) {
    return this.request(path, 'POST', data, extraConfig)
  }

  put(path, data, extraConf = {}) {
    return this.request(path, 'PUT', data, extraConf)
  }

  delete(path, data = {}, extraConf = {}) {
    return this.request(path, 'DELETE', data, extraConf)
  }

  extraResp(response) {
    const data = (response && response.data) || {}
    return (data && data.data) || { err: true, code: data.code, message: data.message }
  }

  async request(path, method = 'GET', paramsData = {}, extraConfig = {}) {
    const { axios } = this
    const config = extend({method,url: path,responseType: 'json'},extraConfig,)
    try {
      const response = await axios(config)
      return this.extraResp(response)
    } catch (err) {
      console.warn('application Service', err)
      return { err: true }
    }
  }
}

export default ApplicationService

Enter fullscreen mode Exit fullscreen mode

UserService.js

import get from 'lodash/get'
import ApplicationService from './ApplicationService'

export default class UserService extends ApplicationService {
  // fetch users list
  users() {
    return this.get('/users')
  }

  // find user by userId
  user(userId){
    return this.get(`/users/${userId}`)
  }
}

Enter fullscreen mode Exit fullscreen mode

Inject to nuxt.js global variable

// ~/plugins/service.js

import UserService from 'UserService.js'

export default (ctx, inject) => {
  ctx.userService = new UserService(ctx)
  inject('userService', ctx.userService)
}

// we can call userService 
this.$userService.users()
this.$userService.user(1)
Enter fullscreen mode Exit fullscreen mode

UserServiceTest.js

import service from 'UserService.js'

test('users', async () => {
  const data = [{name: 'foo', age: 23}]
  service.mockResponse({ data })
  const users = await service.users()
  service.expectCalledWith({ url: '/users' })
  expect(users).toEqual([{name: 'foo', age: 23}])
})
Enter fullscreen mode Exit fullscreen mode

OK, so far you can write independent UserServiceTest.js and test work on.

Do that you have benefit:

  • service object just care how to fetch resource from remote server
  • write more clean and independent test file
  • call service with nuxt global object context with this.$service.user

Hope it can help you :)

💖 💪 🙅 🚩
ihavecoke
mixbo

Posted on June 22, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Use service object in nuxt.js
javascript Use service object in nuxt.js

June 22, 2020