Kiran Evans
Kiran Evans

Reputation: 15

Variable is not updating at the end of the function chain

function newBusRoute() {
    busRoute += 1;
    routeName = "Bus Route " + busRoute;
    routeArrayBusRoutes.push(routeName);
    vehArrayBusRoutes.push(0);
    updateRoutes(routeArrayBusRoutes, vehArrayBusRoutes, "busRoutesListDiv", 600, "maintBus", maintBus, 99, 50, "vehCountBus");
}

function updateRoutes(routeArray, vehArray, listid, cost, maintType, maintCost, eivPlus, capacityPlus, vehCountType) {
    document.getElementById(listid).innerHTML = "";
    for (I in routeArray) {
        document.getElementById(listid).innerHTML += ("<button onclick='editRoute(\""+I+"\", \""+vehArray[I]+"\", \""+vehArray+"\", \""+cost+"\", \""+maintType+"\", \""+maintCost+"\", \""+eivPlus+"\", \""+capacityPlus+"\", \""+vehCountType+"\")'>"+routeArray[I]+"</button>");
    }
}

function editRoute(route, vehCount, vehArray, cost, maintType, maintCost, eivPlus, capacityPlus, vehCountType) {
    $("#mainContainer").fadeOut();
    document.getElementById("screen").innerHTML = (
        "<h1>Bus Route "+route+"</h1>" +
        "<p id='routeVehCount'>Vehicles on this route: "+vehCount +
        "<p><button onclick='addVeh(\""+route+"\", \""+vehArray+"\", \""+cost+"\", \""+maintType+"\", \""+maintCost+"\", \""+eivPlus+"\", \""+capacityPlus+"\", \""+vehCountType+"\")'>+ Add Vehicle | Cost: £600 | Maintenance: £50 per day</button>"
    );
    $("#screen").fadeIn();
    $("#closeButton").fadeIn();
}

function addVeh(route, vehArray, cost, maintType, maintCost, eivPlus, capacityPlus, vehCountType) {
    vehArray[route] += 1;
    vehCountType += 1;
    bank -= cost;
    checkBank;
    maintCost = Number(maintCost);
    maintType += maintCost;
    checkIncome();
    eiv = Number(eiv);
    eiv += Number(eivPlus);
    checkEIV();
    capacity = Number(capacity);
    capacity += capacityPlus;
    checkCapacity();
}

Hi, I've written these functions. I know they look messy but essentially all the variables get passed along the functions from updateRoutes() to addVeh(). All of them work fine, apart from "vehCountBus", which is passed along as vehCountType. No errors are thrown, it just simply doesn't update unless I manually replace vehCountType in addVeh() to vehCountBus.

Why is the value of vehCountType not carried through like the other variables?

Upvotes: 0

Views: 67

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074028

The simple example of your problem is this:

function increaseA(a) {
    a += 1;
}
let a = 1;
increaseA(a);
console.log(a); // Still 1, not 2

The problem is that a += 1 in increaseA updates the parameter a. It has no effect whatsoever on the a variable defined outside of increaseA. When you do

increaseA(a);

the value of a is read, then that value (not a link to the a variable) is passed into increaseA.

If you want to have a function change a variable that isn't defined within the function, your options are:

  1. Have it directly reference the variable by closing over it.
  2. Have it return a new value that you assign to the variable (a = increaseA(a)).

You may be wondering why vehArray[route] += 1; works, given the above. It works because that's changing the state of an object, not the value of a variable/parameter. If you'd done vehArray = [] instead, changing the value of the vehArray parameter, that too wouldn't have any effect outside the function.

You could use that fact to refactor your code to pass an object with named properties into your function, then change the state of the object (assigning new values to its properties). For instance:

function increaseA(object) {
    object.a += 1;
}
let object = {
    a: 1
};
increaseA(object);
console.log(object.a); // 2

Upvotes: 2

Related Questions