From 77620c1699f0080b39f0b67405d070524438ca09 Mon Sep 17 00:00:00 2001 From: shibafu Date: Thu, 6 Aug 2020 09:53:50 +0900 Subject: [PATCH] =?UTF-8?q?x-csrf-token=E3=81=8C=E9=80=81=E3=82=89?= =?UTF-8?q?=E3=82=8C=E3=81=AD=E3=81=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/assets/js/app.ts | 73 +++++++++++++++--------------------- resources/assets/js/fetch.ts | 40 +++++++++++++------- 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/resources/assets/js/app.ts b/resources/assets/js/app.ts index 7267f57..1196678 100644 --- a/resources/assets/js/app.ts +++ b/resources/assets/js/app.ts @@ -1,5 +1,5 @@ import * as Cookies from 'js-cookie'; -import jqXHR = JQuery.jqXHR; +import { fetchPostJson, fetchDeleteJson, ResponseError } from './fetch'; require('./bootstrap'); @@ -41,57 +41,46 @@ $(() => { const isLiked = $this.data('liked'); if (isLiked) { - const callback = (data: any) => { - $this.data('liked', false); - $this.find('.oi-heart').removeClass('text-danger'); - - const count = data.ejaculation ? data.ejaculation.likes_count : 0; - $this.find('.like-count').text(count ? count : ''); - }; - - $.ajax({ - url: '/api/likes/' + encodeURIComponent(targetId), - method: 'delete', - type: 'json', - }) - .then(callback) - .catch(function (xhr: jqXHR) { - if (xhr.status === 404) { - callback(JSON.parse(xhr.responseText)); - return; + fetchDeleteJson(`/api/likes/${encodeURIComponent(targetId)}`) + .then((response) => { + if (response.status === 200 || response.status === 404) { + return response.json(); } + throw new ResponseError(response); + }) + .then((data) => { + $this.data('liked', false); + $this.find('.oi-heart').removeClass('text-danger'); - console.error(xhr); + const count = data.ejaculation ? data.ejaculation.likes_count : 0; + $this.find('.like-count').text(count ? count : ''); + }) + .catch((e) => { + console.error(e); alert('いいねを解除できませんでした。'); }); } else { - const callback = (data: any) => { - $this.data('liked', true); - $this.find('.oi-heart').addClass('text-danger'); + fetchPostJson('/api/likes', { id: targetId }) + .then((response) => { + if (response.status === 200 || response.status === 409) { + return response.json(); + } + throw new ResponseError(response); + }) + .then((data) => { + $this.data('liked', true); + $this.find('.oi-heart').addClass('text-danger'); - const count = data.ejaculation ? data.ejaculation.likes_count : 0; - $this.find('.like-count').text(count ? count : ''); - }; - - $.ajax({ - url: '/api/likes', - method: 'post', - type: 'json', - data: { - id: targetId, - }, - }) - .then(callback) - .catch(function (xhr: jqXHR) { - if (xhr.status === 409) { - callback(JSON.parse(xhr.responseText)); - return; - } else if (xhr.status === 401) { + const count = data.ejaculation ? data.ejaculation.likes_count : 0; + $this.find('.like-count').text(count ? count : ''); + }) + .catch((e) => { + if (e instanceof ResponseError && e.response.status === 401) { alert('いいねするためにはログインしてください。'); return; } - console.error(xhr); + console.error(e); alert('いいねできませんでした。'); }); } diff --git a/resources/assets/js/fetch.ts b/resources/assets/js/fetch.ts index d683e62..128aec4 100644 --- a/resources/assets/js/fetch.ts +++ b/resources/assets/js/fetch.ts @@ -17,41 +17,55 @@ const joinParamsToPath = (path: string, params: QueryParams) => const fetchWrapper = (path: string, options: RequestInit = {}) => fetch(path, { credentials: 'same-origin', - headers, + headers: { ...headers, ...options.headers }, ...options, }); -const fetchWithJson = (path: string, body: any, options: RequestInit = {}) => +const fetchWithJson = (path: string, body?: any, options: RequestInit = {}) => fetchWrapper(path, { - body: JSON.stringify(body), - headers: { 'Content-Type': 'application/json' }, + body: body && JSON.stringify(body), + headers: { 'Content-Type': 'application/json', ...options.headers }, ...options, }); -const fetchWithForm = (path: string, body: any, options: RequestInit = {}) => +const fetchWithForm = (path: string, body?: any, options: RequestInit = {}) => fetchWrapper(path, { - body: stringify(body), - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: body && stringify(body), + headers: { 'Content-Type': 'application/x-www-form-urlencoded', ...options.headers }, ...options, }); export const fetchGet = (path: string, params: QueryParams = {}, options: RequestInit = {}) => fetchWrapper(joinParamsToPath(path, params), { method: 'GET', ...options }); -export const fetchPostJson = (path: string, body: any, options: RequestInit = {}) => +export const fetchPostJson = (path: string, body?: any, options: RequestInit = {}) => fetchWithJson(path, body, { method: 'POST', ...options }); -export const fetchPostForm = (path: string, body: any, options: RequestInit = {}) => +export const fetchPostForm = (path: string, body?: any, options: RequestInit = {}) => fetchWithForm(path, body, { method: 'POST', ...options }); -export const fetchPutJson = (path: string, body: any, options: RequestInit = {}) => +export const fetchPutJson = (path: string, body?: any, options: RequestInit = {}) => fetchWithJson(path, body, { method: 'PUT', ...options }); -export const fetchPutForm = (path: string, body: any, options: RequestInit = {}) => +export const fetchPutForm = (path: string, body?: any, options: RequestInit = {}) => fetchWithForm(path, body, { method: 'PUT', ...options }); -export const fetchDeleteJson = (path: string, body: any, options: RequestInit = {}) => +export const fetchDeleteJson = (path: string, body?: any, options: RequestInit = {}) => fetchWithJson(path, body, { method: 'DELETE', ...options }); -export const fetchDeleteForm = (path: string, body: any, options: RequestInit = {}) => +export const fetchDeleteForm = (path: string, body?: any, options: RequestInit = {}) => fetchWithForm(path, body, { method: 'DELETE', ...options }); + +export class ResponseError extends Error { + response: Response; + + constructor(response: Response, ...rest: any) { + super(...rest); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, ResponseError); + } + + this.name = 'ResponseError'; + this.response = response; + } +}