Forum Discussion

cmpenn's avatar
cmpenn
Contributor
2 years ago

A const value does not work in other files

Here's an example:

File 1:

 

const MAX_SEARCH_DEPTH = 20;

 

 

 

File 2:

 

//USEUNIT File 1

function constantsTest() {
Log.Message(MAX_SEARCH_DEPTH); //Should return 20, instead returns ''
}

 


Any idea what I may be doing wrong?

  • I think it has to do with the value being only locally scoped to the unit.  While within the unit where the constant is declared it's treated as a constant, as soon as you pull that unit into a new unit, it becomes a variable.  Example:

    //USEUNIT Constant
    
    function bar(){
        Log.Message(Constant.TEST_CONST)
        Constant.TEST_CONST = 'yada'
        Log.Message(Constant.TEST_CONST)
    }

     

    In the above example, the first message call returns blank, no matter what I have it set to in the unit "Constant".  But then if I assign it the word "yada", then it returns "yada".

     

    What it looks like is that a constant in a JavaScript unit is just a property of that unit that has no "set" method associated to it.  When you export the unit using modules.export (or //USEUNIT) you're not using the unit as is, you're exporting the unit as an in memory  instance of the unit object which is set up to be more generic.

     

    What I've found, generally, is that while JavaScript in TestComplete works pretty closely to using JavaScript in an actual web application, there are some differences that require work arounds. My best bet for you, for simplicity sake, is make sure you're consistent in your naming convention for constants (variables = camelCase, constants = ALL_UPPER) and then just remaining consistent in how you use those items.  In that case, the "exports" and "require" methodology will work best for you.

     

     

  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor

    Yes.  Scope.  The constant is declared in one file but that doesn't necessarily mean it's scoped to be able to be used in another file.  I'm assuming you're using JavaScript.  In order to use something declared in one unit in another unit, you need to export the item or use the //USEUNIT call.  See https://support.smartbear.com/testcomplete/docs/scripting/calling-routines/declared-in-another-unit/javascript.html 

     

    Here's how I'd change your code

     

    First unit where the constant is declared

     

    const MAX_SEARCH_DEPTH = 20
    
    module.exports.maxSearchDepth = MAX_SEARCH_DEPTH

     

    In the calling unit:

    var constantUnit = requires("constantUnit")
    
    function test (){
       Log.Message(constantUnit.maxSearchDepth)
    }
    • cmpenn's avatar
      cmpenn
      Contributor

      Ah, that's the thing I forgot in my example.

      I *am* using //USEUNIT File1

      I just double-checked, but I'll try your solution as well.

    • cmpenn's avatar
      cmpenn
      Contributor

      Okay, your solution does let me access the value, but it is no longer a constant...which was the main thing I was looking for.

      • tristaanogre's avatar
        tristaanogre
        Esteemed Contributor

        I think it has to do with the value being only locally scoped to the unit.  While within the unit where the constant is declared it's treated as a constant, as soon as you pull that unit into a new unit, it becomes a variable.  Example:

        //USEUNIT Constant
        
        function bar(){
            Log.Message(Constant.TEST_CONST)
            Constant.TEST_CONST = 'yada'
            Log.Message(Constant.TEST_CONST)
        }

         

        In the above example, the first message call returns blank, no matter what I have it set to in the unit "Constant".  But then if I assign it the word "yada", then it returns "yada".

         

        What it looks like is that a constant in a JavaScript unit is just a property of that unit that has no "set" method associated to it.  When you export the unit using modules.export (or //USEUNIT) you're not using the unit as is, you're exporting the unit as an in memory  instance of the unit object which is set up to be more generic.

         

        What I've found, generally, is that while JavaScript in TestComplete works pretty closely to using JavaScript in an actual web application, there are some differences that require work arounds. My best bet for you, for simplicity sake, is make sure you're consistent in your naming convention for constants (variables = camelCase, constants = ALL_UPPER) and then just remaining consistent in how you use those items.  In that case, the "exports" and "require" methodology will work best for you.