I have abstracted some logic for fetching data into its own service.
import type { Todo } from './Todo';
class TodoService {
private async secretFetch() {
const todos = await fetch('https://jsonplaceholder.typicode.com/todos/');
return (await todos.json()) as Todo[];
}
async fetchTodos() {
const todos = await this.secretFetch();
return todos;
}
}
const todoService = new TodoService();
export default todoService;
I would like to use this method as a parameter for useQuery
, but I noticed that the query fails when the method calls another method inside my class.
export default function App() {
const { data: todos, isLoading } = useQuery('todos', todoService.fetchTodos);
if (isLoading) {
return <p> Loading </p>;
}
if (todos.length === 0) {
return <p> There are no todos </p>;
}
return (
<ul>
{todos.map((todo) => (
<li> {todo.title} </li>
))}
</ul>
);
}
Here's an example in Stack blitz: https://stackblitz.com/edit/react-ts-5uxsz5?file=App.tsx
CodePudding user response:
You've lose this
reference
Either create an anonymous function
const { data: todos, isLoading } = useQuery('todos', () => todoService.fetchTodos());
or bind
const { data: todos, isLoading } = useQuery('todos', todoService.fetchTodos.bind(todoService));
CodePudding user response:
this
in the fetchTodos
points to the wrong context.
Either transform the fetchTodos
into an arrow function:
fetchTodos = async () => {
const todos = await this.secretFetch();
return todos;
}
or set the secretFetch
as a static method and access it:
class TodoService {
private static async secretFetch() {
...
}
async fetchTodos() {
const todos = await TodoService.secretFetch();
return todos;
}
}