Chained https requests using promises seem to be out of order

I’m trying to figure out how Promises work with multiple HTTPS requests in Javascript, but I have a problem where the results seem out of order with the request sequence. I’m using an ASP.NET Controller API implementation for a simple calculator, and Javascript to access the API. I seem to have a synchronization issue, but I can’t for the life of me work out why.

The CalculatorController:

using Microsoft.AspNetCore.Mvc;

namespace Wolflight.Calculator.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class CalculatorController : Controller
    {
        private const string TotalName = "Total";


        private decimal RetrieveTotal()
        {
            return ToDecimal(HttpContext.Session.GetString(TotalName));
        }

        private void StoreTotal(decimal value)
        {
            HttpContext.Session.SetString(TotalName, FromDecimal(value));
        }

        private static string FromDecimal(decimal value)
        {
            return value.ToString();
        }

        private static decimal ToDecimal(string? value)
        {
            if (value != null)
            {
                return Decimal.Parse(value);
            }
            else
            {
                return 0M;
            }

        }

        [HttpGet()]
        [Route("/api/Calculator/Total")]
        public decimal? GetTotal()
        {
            return RetrieveTotal();
        }

        [HttpPut()]
        [Route("/api/Calculator/Add")]
        public void AddValue(decimal value)
        {
            StoreTotal(RetrieveTotal() + value);
        }

        [HttpPut()]
        [Route("/api/Calculator/Subtract")]
        public void SubtractValue(decimal value)
        {
            StoreTotal(RetrieveTotal() - value);
        }

        [HttpPut()]
        [Route("/api/Calculator/Multiply")]
        public void MultiplyValue(decimal value)
        {
            StoreTotal(RetrieveTotal() * value);
        }

        [HttpPut()]
        [Route("/api/Calculator/Divide")]
        public void DivideValue(decimal value)
        {
            StoreTotal(RetrieveTotal() / value);
        }


    }
}

The site.js:

const uriBase = "/api/Calculator/";
const uriTotal = uriBase + "Total";
const uriAdd = uriBase + "Add";

let GetTotalValuePromise = function () {
    return new Promise(function (myResolve, myReject) {
        let total = fetch(uriTotal)
            .then(response => response.text())
            .catch(error => myReject('Unable to get total.', error));

        myResolve(total);
    })
};

let PutAddValuePromise = function (addValue) {
    return new Promise(function (myResolve, myReject) {
        fetch(uriAdd + '?value=' + addValue, { method: 'PUT' })
            .catch(error => myReject('Unable to add value.', error));

        myResolve();
    }
    )
};

function DisplayTotal(total) {
    const tBody = document.getElementById('totalDisplay');
    tBody.innerHTML = total;
}

function GetTotal() {
    UpdateDisplay();
}

function AddValue() {
    let value = document.getElementById('addValue').value;

    PutAddValuePromise(value)
        .then(function () {
            UpdateDisplay();
        });
}

function UpdateDisplay() {
    GetTotalValuePromise()
        .then(
            function (total) { DisplayTotal(total); },
            function (message, error) { console.error(message, error); }
        )
}

When I call AddValue() from a form button, the result is that sometimes the /Total call returns the value before the /Add occurs, and sometimes it returns the result after.

e.g.

  • Total = 0
  • Call AddValue, with element addValue as 5.

Network Requests:

  • /Add?value=5 (no response)
  • /Total – Response: 0.

OR

Network Requests:

  • /Add?value=5 (no response)
  • /Total – Response: 5.

Am I missing something in how Promises work, or is the problem on the server side?

If I call GetTotal manually after the AddValue, it always returns the correct value.