skip to Main Content

the problem that im having is that when using functions that return a promise i cant get them to generate the HTML correctly ang therefor i am unable to place it in the correct location.

the code currently creates all the elements from createClientElement but only populates the first one.

the code that calls the promises:

function previousOrders(){

    for (let i=0; i< UniqueOrderIdList.length; i++) {

        var orderItemsByIdURL = base_url + orderItemsPath + url_auth + "&order_id=" + UniqueOrderIdList[i];

        var index = i;

        function getSuccess(obj){

            var data = obj.data;

            console.log(data);
                                    
            for (let i=0; i< data.length; i++){
                var Widget_id = data[i].widget_id
                var Number = data[i].number
                var PencePrice = data[i].pence_price
                var price =  parseFloat(PencePrice/100).toFixed(2)
    
                Promise.all([getProdDesc(Widget_id), getClientId(UniqueOrderIdList[index])])
                .then((values) => {
                    createClientElement(values[1], index).then(test => {

                        console.log(`index: ${index}`);
                        console.log(`number: ${Number}`);
                        console.log(`productDsc: ${values[0]}`);
                        console.log(`ID:${values[1]}`);
                        console.log(`price: ${price}`);

                        var template2 =
                        `<div>
                            <p class="orderdsc" id="orderdsc_${i}">${Number+": "}${values[0]}
                                <span class="orderItemid" id="orderItemid_${i}">ID:${values[1]}</span>
                                <span class="orderPrice" id="orderPrice_${i}">£${price}</span>
                            </p>
                        </div>`

                    $(`#pastOrderItems_${index}`).append(template2);
                    },onError)
                    
                },onError);
                    
            }
    
        }

        $.ajax(orderItemsByIdURL, {type: "GET", data: {},success: getSuccess });
        console.log("success");
    }
}

the getProdDesc funtion:

function getProdDesc(widgetId){
    return new Promise((resolve, reject) => {
        var prodDescURL = base_url + widgetsPath + widgetId + url_auth;
        
          function getSuccess(obj){
            
            if (obj.status == "success") {

                console.log("Got Product:", obj.data);
                var data = obj.data;
              
                var description = data[0].description;

                resolve(description);

            } else if (obj.message) {
                reject(new Error(obj.message));
            } else {
                reject(new Error("Invalid request"));
            }
              
          }
  
          $.ajax(prodDescURL, {type: "GET", data: {},success: getSuccess });
      });
    
}

the getClientId function:

function getClientId(orderId){
    return new Promise((resolve, reject) => {
        setTimeout(()=> {
            var prodDescURL = base_url + ordersPath + orderId + url_auth;

            function getSuccess(obj){
              
              if (obj.status == "success") {

                  console.log("Got Client: ", obj.data);
                  var data = obj.data;
                
                  var clientId = data[0].client_id;
                  
                  resolve(clientId);

              } else if (obj.message) {
                  reject(new Error(obj.message));
              } else {
                  reject(new Error("Invalid request"));
              }
                
            }

            $.ajax(prodDescURL, {type: "GET", data: {},success: getSuccess });
        }, 200)

      });
}

the createClientElement funtion

function createClientElement(client, i){
    return new Promise((resolve, reject) =>{
        
        var clientURL = base_url + clientPath + client + url_auth

        function getSuccess(obj){

            var data = obj.data;
            var client_name = data[0].name
            var client_address = data[0].address
            var client_phone = data[0].phone
            var client_email = data[0].email


            var template =
            `<div class="clientMain">
                <div id="clients">
                    <p class="client top" id="clientName">Client name: ${client_name}</p>
                    <p class="client" id="clientAddress">Client address: ${client_address}</p>
                    <p class="client" id="clientPhone">Client phone: ${client_phone}</p>
                    <p class="client bottom" id="clientEmail">Client email: ${client_email}</p>
                </div>
                <div class="order" id="pastOrderItems_${i}">
                
                </div>
            </div>
            `
            $("#pastOrdersINPUT").append(template);

            resolve("success");
        }

        $.ajax(clientURL, {type: "GET", data: {},success: getSuccess });
    });
}

I know that each function works individually and I’ve gone a little code blind trying to work this out.

reference for what the final HTML result should look like (variable inputs left in for ease of reference):

<div id="pastOrdersINPUT">
<div class="clientMain">
                <div id="clients">
                    <p class="client top" id="clientName">Client name: ${client_name}</p>
                    <p class="client" id="clientAddress">Client address: ${client_address}</p>
                    <p class="client" id="clientPhone">Client phone: ${client_phone}</p>
                    <p class="client bottom" id="clientEmail">Client email: ${client_email}</p>
                </div>
                <div class="order" id="pastOrderItems_${i}">
                <div>
                            <p class="orderdsc" id="orderdsc_${i}">${Number+": "}${values[0]}
                                <span class="orderItemid" id="orderItemid_${i}">ID:${values[1]}</span>
                                <span class="orderPrice" id="orderPrice_${i}">£${price}</span>
                            </p>
                        </div>
                </div>
            </div>
</div>

2

Answers


  1. The function getSuccess(obj) in previousOrders() referred to index, but by the time those ajax call succeed they would all get the same index value because index has function scope, not block scope. Try changing var index = i; to let index = i;

    Login or Signup to reply.
  2. You should really consider using async await to make the code more readable and maintainable.

    I have made some changes to make it run using a dummy endpoint, and marked some spots that were important.

    Maybe you can try to do the changes in your code to see if it would work:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    
        <script>
          function createClientElement(client, i) {
            return new Promise((resolve, reject) => {
              var clientURL = "https://jsonplaceholder.typicode.com/users";
    
              function getSuccess(data) {
                var client_name = data[0].name;
                var client_address = data[0].address.street;
                var client_phone = data[0].phone;
                var client_email = data[0].website;
    
                var template = `<div class="clientMain">
                    <div id="clients">
                        <p class="client top" id="clientName">Client name: ${client_name}</p>
                        <p class="client" id="clientAddress">Client address: ${client_address}</p>
                        <p class="client" id="clientPhone">Client phone: ${client_phone}</p>
                        <p class="client bottom" id="clientEmail">Client email: ${client_email}</p>
                    </div>
                    <div class="order" id="pastOrderItems_${i}">
                    
                    </div>
                </div>
                `;
                $("#pastOrdersINPUT").append(template);
    
                resolve(i); //🟥 RETURNS THE PROPER INDEX <<===== #############################
              }
    
              $.ajax(clientURL, { type: "GET", data: {}, success: getSuccess });
            });
          }
    
          function getClientId(orderId) {
            return new Promise((resolve, reject) => {
              setTimeout(() => {
                var prodDescURL = "https://jsonplaceholder.typicode.com/comments?postId=1";
    
                function getSuccess(obj) {
                  if (obj) {
                    var clientId = obj[0].id;
    
                    resolve(clientId);
                  } else if (obj.message) {
                    reject(new Error(obj.message));
                  } else {
                    reject(new Error("Invalid request"));
                  }
                }
    
                $.ajax(prodDescURL, { type: "GET", data: {}, success: getSuccess });
              }, 200);
            });
          }
    
          function getProdDesc(widgetId) {
            return new Promise((resolve, reject) => {
              var prodDescURL = "https://jsonplaceholder.typicode.com/comments?postId=1";
    
              function getSuccess(obj) {
                if (obj) {
                  var description = obj[0].body;
    
                  resolve(description);
                } else if (obj.message) {
                  reject(new Error(obj.message));
                } else {
                  reject(new Error("Invalid request"));
                }
              }
    
              $.ajax(prodDescURL, { type: "GET", data: {}, success: getSuccess });
            });
          }
    
          function previousOrders() {
            for (let i = 0; i < 2; i++) {
              var orderItemsByIdURL = "https://jsonplaceholder.typicode.com/posts/1/comments";
    
              var index = 0;
    
              function onError(error) {
                console.log(error);
              }
    
              function getSuccess(data) {
                for (let i = 0; i < data.length; i++) {
                  var Widget_id = data[i].id;
                  var Number = data[i].id;
                  var PencePrice = data[i].id;
                  var price = parseFloat(PencePrice / 100).toFixed(2);
    
                  Promise.all([getProdDesc(Widget_id), getClientId(1)]).then((values) => {
                    index++; //🟥 increase the index <<===== #############################
    
                    createClientElement(values[1], index).then((_index) => { //🟥 receives the proper index <<===== #############################
                      var template2 = `<div>
                            <p class="orderdsc" id="orderdsc_${i}">${Number + ": "}${values[0]}
                                <span class="orderItemid" id="orderItemid_${i}">ID:${values[1]}</span>
                                <span class="orderPrice" id="orderPrice_${i}">£${price}</span>
                            </p>
                        </div>`;
    
                      $(`#pastOrderItems_${_index}`).append(template2); //🟥 uses the proper index <<===== #############################
                    }, onError);
                  }, onError);
                }
              }
    
              $.ajax(orderItemsByIdURL, { type: "GET", data: {}, success: getSuccess });
              console.log("success");
            }
          }
    
          previousOrders();
        </script>
      </head>
      <body>
        <div id="pastOrdersINPUT"></div>
      </body>
    </html>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search