
Join the Conversation!
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
"Please login to view comments"
Subscribing gives you access to the comments so you can share your ideas, ask questions, and connect with others.
Complete source code for this lesson is available at
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
##Looks like we found a thief monkey By the way, I liked the trick how you reached till here. You have a good sense of humor. You will improve a lot if you join our course with this passion.
var
(function-scoped, outdated)let
(block-scoped, modern and recommended)const
(block-scoped, cannot be reassigned)_
, or $
let let = 5;
is invalid)myVar
and myvar
are different)string
, number
, boolean
, null
, undefined
, bigint
, symbol
Objects
, Arrays
, Functions
Subscribing gives you access to a brief, insightful summary of each lecture to stay on track.
00:00:02 Let's use the API route we created in the last lesson to generate an answer and use it on the front end.
00:00:08 We can start by modifying the question details page.
00:00:11 That is the one with the question ID that we have been on for the last couple of modules.
00:00:16 Here, right at the bottom in the answer form, we can also pass a question title equal to question.title as well as a question content.
00:00:28 equal to question.content.
00:00:31 Then make sure you're using the latest version of the MDX editor.
00:00:36 At the time of the recording, we're looking at 3.21. I think I'm on one, but we need to have the version four.
00:00:43 So just make sure that it is four or higher, and then I'll just run npm install one more time to install this newer version that I just typed in,
00:00:51 because previous versions of this package had an issue with the code editor.
00:00:55 Then let's move over into the answer form and let's generate the answer.
00:01:00 First, I'll accept these new props for passing into it, such as the question title, as well as the question content.
00:01:09 Now I can turn this into an actual interface of props, which we can define right here at the top.
00:01:16 interface props, and it'll have a question ID, question title, and question content.
00:01:22 Next, let's make sure that only authenticated users are able to generate AI answers, not to rack up our bill.
00:01:29 We can do that by saying const session is equal to use session coming from NextAuth React.
00:01:36 Next, let's head over into our handle submit form.
00:01:40 And below if results success, below this toast, let's say if.
00:01:45 editorRef.current, then we can clear the markdown by saying editorRef.current.setMarkdown to be equal to an empty string.
00:01:57 And finally, we can create a new function called const generateAIAnswer, which will be equal to an async function where we'll first check if a session
00:02:10 status is not equal to authenticated, And if that is the case, we'll simply return a toast with a title of please log in and a description of you need
00:02:23 to be logged in to be able to use this feature.
00:02:26 In the future, if you want to implement some kind of payment functionalities in your app, this would be the perfect use case to start charging for pro
00:02:34 features of your app, such as generating AI answers.
00:02:37 So only pro users can then leave AI generator responses.
00:02:41 And we can also set, is AI submitting to true?
00:02:45 Because if we don't return out of this, that means that we are authenticated.
00:02:50 So let's open up a try and catch block.
00:02:53 In the catch, I'll simply return a toast that'll have a title equal to error.
00:03:01 It'll have a description of something like error.message.
00:03:06 And finally, a variant will be set to destructive.
00:03:09 And we can also add a finally clause.
00:03:13 Where will set AI is submitting to false, whatever happens.
00:03:17 Oh, and it looks like I forgot to close this if statement right here.
00:03:20 The rest of the code should happen below the if statement.
00:03:23 Now we can see a type error with this description.
00:03:26 So we can say if error is an instance of error, then we can render the error message.
00:03:35 Else we can simply say something like there was a problem with your request.
00:03:42 There we go.
00:03:44 And we are ready to implement the try part of the block where we are ready to call this API.
00:03:50 In here, we can say await API.ai.getAnswer.
00:03:58 Yep, it is that simple.
00:03:59 And to it, you have to pass two params, the question title, as well as the question content.
00:04:08 I told you that later on, we'll be passing the answer that you currently have typed into it.
00:04:13 So bear with me, we'll do that very soon.
00:04:15 But for now, let's make the AI generate its own answer.
00:04:20 Now, where are we going to get this API from?
00:04:22 From lib API, of course.
00:04:25 And we're going to get some response out of this request.
00:04:28 So let's say const and destructure the success state, the data and the error and make it equal to the await call that we just made right here.
00:04:39 We can then check if there is no success.
00:04:42 In that case, we can return a toast and give it a title of error, a description of something like error.message and a variant of destructive.
00:04:55 And if we have a successful response, then we can generate a formatted answer by saying const formatted answer is equal to data.replace And basically we
00:05:09 want to replace every break tag that looks something like this globally across the entire file with an empty space.
00:05:17 So break replaced by a space.
00:05:19 We want to put it to a string.
00:05:22 and we wanna trim it in case there are some extra spaces.
00:05:26 Finally, we wanna check if we have access to the editor ref dot current.
00:05:32 That means the actual editor where we're typing the response.
00:05:35 If we do have access to it, then we can say editor ref dot current dot set markdown to the formatted answer.
00:05:43 We can also validate that content field automatically by saying form dot set value of the content to the formatted answer and we can do the same thing
00:05:56 with form.trigger the validation for the content.
00:06:00 This way we'll automatically know that it has been validated.
00:06:03 We don't have a lot of reason to manually validate the fields because typically they're validated when you type, but here you're not actually typing.
00:06:10 You get the AI to do typing for you.
00:06:13 Oh, and I just noticed that this was supposed to be within this if statement right here.
00:06:17 So let's put it there.
00:06:19 And then let's exit this if statement and let's render a toast with a title of success.
00:06:26 and a description of AI answer has been generated.
00:06:31 Perfect.
00:06:32 Finally, back in the form right below where we say generate AI answer.
00:06:37 I think that's here.
00:06:38 Right here, we have a button that generates that AI answer.
00:06:42 So let's make it do its thing.
00:06:44 Let's give it an on-click listener and make it equal to generate AI answer.
00:06:50 And that's it.
00:06:51 So we are ready to test it out.
00:06:53 Back in the browser, we are ready to test it out.
00:06:55 So head down below a specific question and click the magic generate AI answer button.
00:07:01 It'll say generating, these requests typically do take some time.
00:07:06 But this time we got an error message saying signal is aborted without reason.
00:07:11 This happens because we set a five second limit for the fetch requests.
00:07:16 And we've done that within our handlers fetch.ts.
00:07:21 See this timeout right here under options?
00:07:24 Well, we need to increase it to a bit of a higher number because it can take some time for AI to generate its answers, which means that we have to extend
00:07:31 the time window.
00:07:32 So instead of 5,000, let's actually make this 100,000 to give it enough time to generate its answer.
00:07:38 Once you do that, we are ready to test it out one more time.
00:07:41 So click generate AI answer.
00:07:43 This time you'll see it'll say generating for a bit of a longer time.
00:07:47 but hopefully it comes up with something nice.
00:07:50 And there we go, success.
00:07:51 AI generated answer has been generated, and you can see the full markdown response right here.
00:07:57 Understanding the data renderer component, it's a versatile tool in the web development.
00:08:02 How it works is it accepts specific data inputs, data detections, rendering logic, and it even provides a perfectly formatted example code within an MDX
00:08:13 code block.
00:08:14 How cool is that?
00:08:15 And you can even post an answer right here in a matter of seconds.
00:08:20 It took us a lot of time to write this with proper formatting and everything, but AI did it in a matter of seconds, providing us the perfect response to
00:08:29 this person's question.
00:08:30 But our app would be kind of funny.
00:08:33 And since people are too lazy when providing answers, nobody would actually type anything.
00:08:38 They would just click this button and give the response to get all the clout.
00:08:42 And that would kind of render our app useless.
00:08:45 Proper questions, but AI-generated answers, which is what nobody likes to see.
00:08:50 So in the next lesson, alongside the question title and the question content, will pass the current answer that you as the user or the person answering
00:09:00 the question have typed in already and then it'll take your answer into account alongside the question title and question content to generate the final answer.
00:09:10 Basically to enhance the answer that you already wrote and return it in a nicely formatted way.
00:09:17 So let's do that in the next lesson.