I'm using the auth0 token provided by the user on login to make api calls via useAuth0.getTokenSilently.
In this example, fetchTodoList
, addTodoItem
, and updateTodoItem
all require a token for authorization. I'd like to be able to extract these functions out in to a separate file (like utils/api-client.js
and import them without having to explicitly pass in the token.
import React, { useContext } from 'react'
import { Link, useParams } from 'react-router-dom'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCircle, faList } from '@fortawesome/free-solid-svg-icons'
import axios from 'axios'
import { queryCache, useMutation, useQuery } from 'react-query'
import { TodoItem } from '../models/TodoItem'
import { TodoInput } from './TodoInput'
import { TodoList as TodoListComponent } from './TodoList'
import { TodoListsContext } from '../store/todolists'
import { TodoListName } from './TodoListName'
import { TodoList } from '../models/TodoList'
import { useAuth0 } from '../utils/react-auth0-wrapper'
export const EditTodoList = () => {
const { getTokenSilently } = useAuth0()
const fetchTodoList = async (todoListId: number): Promise<TodoList> => {
try {
const token = await getTokenSilently!()
const { data } = await axios.get(
`/api/TodoLists/${todoListId}`,
{
headers: {
Authorization: `Bearer ${token}`
}
}
)
return data
} catch (error) {
return error
}
}
const addTodoItem = async (todoItem: TodoItem): Promise<TodoItem> => {
try {
const token = await getTokenSilently!()
const { data } = await axios.post(
'/api/TodoItems',
todoItem,
{
headers: {
Authorization: `Bearer ${token}`,
}
}
)
return data
} catch (addTodoListError) {
return addTodoListError
}
}
const updateTodoItem = async (todoItem: TodoItem) => {
try {
const token = await getTokenSilently!()
const { data } = await axios.put(
'/api/TodoItems',
todoItem,
{
headers: {
Authorization: `Bearer ${token}`,
}
}
)
return data
} catch (addTodoListError) {
return addTodoListError
}
}
const [updateTodoItemMutation] = useMutation(updateTodoItem, {
onSuccess: () => {
queryCache.refetchQueries(['todoList', todoListId])
}
})
const [addTodoItemMutation] = useMutation(addTodoItem, {
onSuccess: () => {
console.log('success')
queryCache.refetchQueries(['todoList', todoListId])
}
})
const onAddTodoItem = async (todoItem: TodoItem) => {
try {
await addTodoItemMutation({
...todoItem,
todoListId: parseInt(todoListId, 10)
})
} catch (error) {
// Uh oh, something went wrong
}
}
const { todoListId } = useParams()
const { status, data: todoList, error } = useQuery(['todoList', todoListId], () => fetchTodoList(todoListId))
const { todoLists, setTodoList } = useContext(TodoListsContext)
const todoListIndex = todoLists.findIndex(
list => todoListId === list.id.toString()
)
const setTodoItems = (todoItems: TodoItem[]) => {
// if(todoList) {
// const list = { ...todoList, todoItems }
// setTodoList(todoListIndex, list)
// }
}
const setTodoListName = (name: string) => {
// setTodoList(todoListIndex, { ...todoList, name })
}
return (
<>
<Link className="block flex align-items-center mt-8" to="/">
<span className="fa-layers fa-fw fa-3x block m-auto group">
<FontAwesomeIcon
icon={faCircle}
className="text-teal-500 transition-all duration-200 ease-in-out group-hover:text-teal-600"
/>
<FontAwesomeIcon icon={faList} inverse transform="shrink-8" />
</span>
</Link>
{status === 'success' && !!todoList && (
<>
<TodoListName
todoListName={todoList.name}
setTodoListName={setTodoListName}
/>
<TodoInput
onAddTodoItem={onAddTodoItem}
/>
<TodoListComponent
todoItems={todoList.todoItems}
setTodoItems={setTodoItems}
updateTodo={updateTodoItemMutation}
/>
</>
)}
</>
)
}
Here's a link to the repo: https://github.com/gpspake/todo-client