Trying to figure out how to target my error response to display in input div with AJAX jQuery from built Python api

This is probably an easy thing to figure out but I can’t find an answer anywhere. I’m having trouble figuring out how to target the error for each given error response for each input. When I catch the error I’m able to get the response error by console logging it but how do I target and single out where it’s coming from so I’m able to display it in error divs in my HTML?

HTML

<html>
<head>
  <title>LuckyNum</title>
  <script src="https://unpkg.com/jquery"></script>
</head>
<body>

<form id="lucky-form">
  <div>Name: <input id="name"> <b id="name-err"></b> </div>
  <div>Birth Year: <input id="year"> <b id="year-err"></b> </div>
  <div>Email: <input id="email"> <b id="email-err"></b> </div>
  <div>Color: <input id="color"> <b id="color-err"></b> </div>
  <button>I Want To Feel Lucky!</button>
</form>

<div id="lucky-results"></div>

<script src="https://unpkg.com/axios/dist/axios.js"></script>
<script src="/static/lucky.js"></script>

</body>
</html>

jQuery

/** processForm: get data from form and make AJAX call to our API. */

async function processForm(evt) {
    evt.preventDefault();
    try {
        const resp = await axios({
            method: 'post',
            url: '/api/get-lucky-num',
            data: {
                name: $("#name").val(),
                year: $("#year").val(),
                email: $("#email").val(),
                color: $("#color").val()
            }
        });
        handleResponse(resp);
    } catch(error) {
        const err = error.response.data.error;
        console.log(err)
    }
}
        
/** handleResponse: deal with response from our lucky-num API. */

function handleResponse(resp) {
    const randNum = resp.data.num;
    const yearNum = resp.data.year;
    $("#lucky-results").append(`<p>Your lucky number is ${randNum.num} (${randNum.fact}).</p>
                                <p>Your birth year ${yearNum.num} fact is ${yearNum.fact}.`)
                                
}


$("#lucky-form").on("submit", processForm);
        

API

from flask import Flask, render_template, jsonify, request
import requests
import random

app = Flask(__name__)


@app.route("/")
def homepage():
    """Show homepage."""

    return render_template("index.html")

@app.route('/api/get-lucky-num', methods=["POST"])
def create_user():

    name = request.json['name']
    if name == "":
        return jsonify(error=str("Name is required.")), 500
    
    year = request.json['year']
    if year == "":
        return jsonify(error=str("Year is required.")), 500
    if int(year) < 1900:
        return jsonify(error=str("Year must be greater than 1900")), 500
    elif int(year) > 2000:
        return jsonify(error=str("Year must be less than 2000")), 500
    
    email = request.json["email"]
    if email == "":
        return jsonify(error=str("Email is required.")), 500
    
    color = request.json["color"]
    if color == "":
        return jsonify(error=str("Color is required.")), 500
    if not color in ["red", "green", "orange", "blue"]:
        return jsonify(error=str("Invalid value, must be one of: red, green, orange, blue.")), 500

    new_num = jsonify(name=name, year=year, email=email, color=color)

    if new_num:
        rand_num = random.randint(1,101)
        num_resp = requests.get(f"http://numbersapi.com/{rand_num}?json")
        num_data = num_resp.json()
        num_fact = num_data["text"]
        num_num = num_data["number"]
        num = {'fact': num_fact, 'num': num_num}
        year_resp = requests.get(f"http://numbersapi.com/{year}/year?json")
        year_data = year_resp.json()
        year_fact = year_data["text"]
        year_num = year_data["number"]
        year = {'fact': year_fact, 'num': year_num}


        return jsonify(num=num, year=year)

    return (new_num, 201)

Answer

change flask route logic to detect the type of error

In api.py

@app.route('/api/get-lucky-num', methods=["POST"])
def create_user():

    name = request.json['name']
    if name == "":
        return jsonify(name_err=str("Name is required.")), 500
    
    year = request.json['year']
    if year == "":
        return jsonify(year_err=str("Year is required.")), 500
    if int(year) < 1900:
        return jsonify(year_err=str("Year must be greater than 1900")), 500
    elif int(year) > 2000:
        return jsonify(year_err=str("Year must be less than 2000")), 500
    
    email = request.json["email"]
    if email == "":
        return jsonify(email_err=str("Email is required.")), 500
    
    color = request.json["color"]
    if color == "":
        return jsonify(color_err=str("Color is required.")), 500
    if not color in ["red", "green", "orange", "blue"]:
        return jsonify(color_err=str("Invalid value, must be one of: red, green, orange, blue.")), 500

....

In index.html change error id(s)

....

    <form id="lucky-form">
        <div>Name: <input id="name"> <b id="name_err"></b> </div>
        <div>Birth Year: <input id="year"> <b id="year_err"></b> </div>
        <div>Email: <input id="email"> <b id="email_err"></b> </div>
        <div>Color: <input id="color"> <b id="color_err"></b> </div>
        <button>I Want To Feel Lucky!</button>
    </form>

....

In lucky.js use jquery to show errors

...

async function processForm(evt) {
    evt.preventDefault();
    try {
        $('#name_err').html('');
        $('#year_err').html('');
        $('#email_err').html('');
        $('#color_err').html('');
        const resp = await axios({
            method: 'post',
            url: '/api/get-lucky-num',
            data: {
                name: $("#name").val(),
                year: $("#year").val(),
                email: $("#email").val(),
                color: $("#color").val()
            }
        });
        handleResponse(resp);
    } catch (error) {
        const err = error.response.data;
        for (key in err) {
            $('#'+key).html(err[key]);
        }
            
    }
}
....

Leave a Reply

Your email address will not be published. Required fields are marked *