We just upgraded from CF2018 to CF2021, and I'm tr...
# cfml-general
b
We just upgraded from CF2018 to CF2021, and I'm trying to make use of
static
for a class variable. I have instance methods that attempt to reference this static variable, but in doing so I'm getting an error:
Copy code
Variable CANCEL_ERROR_TEXT is undefined in static context.
I've tried defining a static block and just declaring it as
static.CANCEL_ERROR_TEXT
, referencing it as
static.CANCEL_ERROR_TEXT
and
Customer::CANCEL_ERROR_TEXT
, and just about everything in the Adobe docs. The only thing that does the trick is to place the variable in the init method, which doesn't seem right to me. Am I missing something blatantly obvious here?
w
dont those declarations go in the pseudo constructor area?
☝🏻 1
paste some code perhaps
r
Place static variables inside a static block at the top of your component.
Copy code
component {
    static {
        public static.CANCEL_ERROR_TEXT = "Oops!";
    }
}
You also need to import the component into the page you want to use it on.
b
oh yeah sorry lemme clarify. i've done it within a static block in the psuedo-constructor area. the only thing calling this variable is the component itself - lemme get you some code
r
You can import the static model at the top of a page or component that needs it.
Copy code
import Models.static.MESSAGES;

component {
    function foo() {
        writeOutput(Customer::CANCEL_ERROR_TEXT);
    }
}
b
Copy code
component name="Customer" initmethod="new" output=false extends="Container.API" {
	// component properties

	static {
		static.PARENT_CHILD_CANCEL_ERROR = "Customer with an active Parent/Child relationship may not be canceled.";
	}

	public Customer function new() {
		this = super.new(argumentCollection=arguments);
		this.Since = Now();
		this.balance_status_dt = Now();
		this.external_uuid = CreateUUID();
		return this;
	}

	// other methods...

	public struct function cancel(boolean tag=false, boolean markFraud=false, boolean adminCancel=false, string maxMindTag="", refund=false) {

		if (this.hasActiveParentChildRelationship()) {
			// this doesn't throw as expected, 
			throw(type="VALIDATION", message=Customer::PARENT_CHILD_CANCEL_ERROR);
		}
		var res = this.cancel_stuff(argumentCollection=arguments);

			// more stuff

		return res;
	}
}
does not seem to work
r
You would just reference static.PARENT_CHILD_CANCEL_ERROR when used inside the component the static variable is declared in. Use Customer::PARENT_CHILD_CANCEL_ERROR when you import Customer into a cfm template or another component.
b
changing
Customer::PARENT_CHILD_CANCEL_ERROR
to
static.PARENT_CHILD_CANCEL_ERROR
makes no difference
r
I believe you can only use static variables in static methods in the component they are declared in.
b
ah, i was afraid of that
r
I generally put all my static message variables in a single component. Then import that component into the pages/components that need to reference those static message variables.
So, in your case I would put the static block in a component called static.MESSAGES. Then
import static.MESSAGES
as the first line of your Customer component, before the component declaration. Then reference the message using
MESSAGES::PARENT_CHILD_CANCEL_ERROR
.
b
that is a really good idea! thanks for the help
a
Pretty sure static methods exist on the class (not the instance) so basically the life of the JVM so you may have to restart if you are messing around with the code.
➕ 1
w
based on that last statement, is there no other way to refresh/update static vars during dev short of a jvm restart?
r
I believe clearing the component cache through the admin also works.
I actually have a static method that populates all my static variables from a database and an application restart works as well. 🤷🏻‍♂️
Well, I guess it's just changing the static variables that were already declared in that case.
w
ok, just curious, not using them anywhere (yet? ever?)