Getting unanswered questions from the REST API

We are going to start interacting with the REST API on the home page when displaying the list of unanswered questions. The HomePage component won't actually change, but the getUnansweredQuestions function in QuestionsData.ts will. In getUnansweredQuestions, we'll leverage the native browser fetch function to interact with our REST API. If you haven't already, let's open Visual Studio Code and carry out the following steps:

  1. Open QuestionsData.ts, find the getUnansweredQuestions function, and replace the implementation with the following content:
export const getUnansweredQuestions = async (): Promise<QuestionData[]> => {
let unansweredQuestions: QuestionData[] = [];

// TODO - call api/questions/unanswered
// TODO - put response body in unansweredQuestions

return unansweredQuestions;
};

The function takes exactly the same parameters and returns the same type as before, so the components that consume this function shouldn't be impacted by the changes we are about to make.

  1. Let's call fetch to request unanswered questions from our backend:
export const getUnansweredQuestions = async (): Promise<QuestionData[]> => {
let unansweredQuestions: QuestionData[] = [];

await fetch('http://localhost:17525/api/questions/unanswered')

// TODO - put response body in unansweredQuestions

return unansweredQuestions;
};

So, for a GET request, we simply put the path we are requesting in the fetch argument. If your REST API is running on a different port, then don't forget to change the path so that it calls your REST API.

Notice the await keyword before the fetch call. This is because it is an asynchronous function and we want to wait for its promises to be resolved before the next statement is executed. 

  1. fetch is promise-based and has a then method that is called when the HTTP response arrives. Let's implement this:
export const getUnansweredQuestions = async (): Promise<QuestionData[]> => {
let unansweredQuestions: QuestionData[] = [];

await fetch('http://localhost:17525/api/questions/unanswered')
.then(res => res.json())

// TODO - put response body in unansweredQuestions

return unansweredQuestions;
};

The then method allows us to interact with items in the response body. Here are some useful properties we could interact with:

    • ok: Whether the response was successful (in other words, whether the HTTP status code is in the range 200-299)
    • status: The HTTP status code for the response
    • headers: An object that gives access to the headers in the HTTP response

Notice that we have used a method called json to request the parsed JSON body.

  1. The json method is promised-based, so we need another then method to get the parsed JSON:
export const getUnansweredQuestions = async (): Promise<QuestionData[]> => {
let unansweredQuestions: QuestionData[] = [];

await fetch('http://localhost:17525/api/questions/unanswered')
.then(res => res.json())
.then(body => {
unansweredQuestions = body;
})

return unansweredQuestions;
};
  1. We can catch any network errors in a catch method:
export const getUnansweredQuestions = async (): Promise<QuestionData[]> => {
let unansweredQuestions: QuestionData[] = [];

await fetch('http://localhost:17525/api/questions/unanswered')
.then(res => res.json())
.then(body => {
unansweredQuestions = body;
})
.catch(err => {
console.error(err);
});

return unansweredQuestions;
};

We simply output any errors to the console.

It is important to note that requests that contain HTTP error codes are not handled by the catch method. HTTP errors must be handled in the first then method by looking at the ok or status properties on the response parameter.
  1. Let's give this a try then. First, let's open the backend project in Visual Studio and run it. We'll leave this running for the whole of this chapter.
  2. Back in Visual Studio Code, start our frontend by typing npm start in the Terminal. When the app runs, we get the following error:

The problem here is that the created property is deserialized as a string and not a Date object like the Question component expects.

  1. Let's resolve this by mapping the created property to a Date object:
export const getUnansweredQuestions = async (): Promise<QuestionData[]> => {
let unansweredQuestions: QuestionData[] = [];

await fetch('http://localhost:17525/api/questions/unanswered')
.then(res => res.json())
.then(body => {
unansweredQuestions = body;
})
.catch(err => {
console.error(err);
});

return unansweredQuestions.map(question => ({
...question,
created: new Date(question.created),
}));
};

We use the array map function to iterate through all of the questions returning a copy of the original question (using the spread syntax) and then overwriting the created property with a Date object from the string date.

  1. If we save the file and look at the running app, we'll see the unanswered questions rendered correctly.

Great stuff; our React app is now interacting with our REST API!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.8.216