[Coldbox 4] utility.cfc

Hello,

Where would I place a utility.cfc with various methods inside of it?

Would the convention naming be utility.cfc or utilities.cfc?

Is it even good practice to have a utility cfc, anymore?

Thank you,
Ryan Hinton

There’s no convention for that. You can just stick it in your /models directory (which is the convention for CFCs) and then wire it in wherever you need it like so:

component {
property name=“utility” inject=“utility”;

function foo() {
utility.doSomething();
}

}

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Excellent! I just want to make sure I do everything according to what you guys recommend.

Thank you, Brad!

Hi Brad,

I’m new to using the injection and Wirebox.

I have an api module created and placed the utillity.cfc within the modules.api.models folder.
I am certain that I don’t have something configured correctly in order to get utility.cfc injected into my api.properly.

I’m reading through the wirebox refcard and I don’t see anything about how to set up a cfc with wirebox located in a module.
I don’t think I should be using the config/wirebox.cfc to have it point to the utility in the api module because then the module is dependent on a configuration outside of the the module.
I noticed a couple of minor references about wirebox within the api moduleConfig.cfc and I am thinking that it would need to be set up there somehow, but not quite sure of the syntax to use.
Would I create a WireBox configuation structure DSL within the api moduleConfig configure() method?

Thank you for your time!
Ryan Hinton

Sub folders don’t get scanned by default aka non recursive, you may need to look into MapDirectory() to achieve what you’re looking for.

Thank you, Andrew.

I found something of interest which sounds like the integrated WireBox automatically looks for the models convention folder in all active modules. The following link is the reference found if you search for “scanLocations” heading. http://wiki.coldbox.org/wiki/WireBox.cfm#Configuring_

Unfortunately, I’m not seeing it work this way

Here is what it says:

scanLocations

The instantiation paths that this Injector will have registered to do object locations in order. So if you request an object called Service and no mapping has been configured for it, then WireBox will search all these scan locations for a Service.cfc in the specified order. The last lookup is the no namespace lookup which basically represents a createObject(“component”,“Service”) call. If you are using WireBox within a ColdBox application, ColdBox will register the models convention folder for you and also whenever a ColdBox module is activated, that module’s model convention folder will be added here too.

Important: Please note that order of declaration is the same as order of lookup, so it really matters. Also note that this setting only makes sense if you do not like to create mappings for objects and you just want WireBox to discover them for you.

wirebox.scanLocations = ["model","transfer.com","org.majano"]

 

I am attempting to see if by removing all scanLocations, then the defaults should work with the last no namespace lookup. I then remove the property in my api cfc located in the handler folder. Then I attempted to use injector.getInstance(‘models.utility’) but get an error stating that variable injector is undefined. I am also making sure to use fwreinit in the url every time.

I will keep testing around with this, but if you or anyone understands this no namespace with modules, I would love any recommendations.

Thank you,
Ryan Hinton

If you drop it in the models folder it will be scanned when the framework is reinited. Unless there is some special configuration needed, like inject init stuff then you shouldn’t need to add them anywhere else.

But yes, if you need to do it in a module, then the best place to set it up is the ModuleConfig.cfc

Try with the CFC name without the path, like this.

injector.getInstance(‘utility’);

When I attempt to use the injector as you suggested, I keep getting an error.

Type: Expression
Messages: Variable INJECTOR is undefined.

What I have in the top of the code is:
component {

Sorry I pressed TAB key to indent which doesn’t work in google and instead it sent the email unfinished, con’d below

What I have in the top of my handlers.invoice cfc is:
component {
property name=‘utility’ inject=‘utility’;

i have it getting called in a create function using:
local.jsonKeyVals = injector.instance(‘utility’).makeJSONkeyValPair(local.jsonData);

This last line is where it errors.

I only did that example because that is what you posted, but you should inject wirebox if it is something it is not injected automatically.

If you have this

property name=‘utility’ inject=‘utility’;

Then you reference it like this

utility.makeJSONkeyValPair(local.jsonData);

Since I have wirebox integrated with Coldbox, it should be looking in the Modules automatically, right? Maybe I am way off on how this runs.

That assumption is correct, it will follow the conventions defined. But check the other reply on how to use it, that I posted.

OK, i had to leave work now but I will try that and report back when I am behind a computer to test.

Thank you, Andrew!

Good Morning!

I have tested by only having property name=‘utility’ inject=‘utility’;
just under component {

I changed the code from injector.instance(‘utility’).makeJSONkeyValPair(local.jsonData); to using

utility.makeJSONkeyValPair(local.jsonData);

I did a hard refresh with fwreinit=1 in the URL.

I receive an error stating that utility is undefined.

Any ideas?

Thank you,
Ryan

Sorry, I was out for most of yesterday so I just caught up with this thread.

For about getInstance() for now. That’s a valid way to get an object instance, but it’s unnecessary right now and just a red herring.
Also, forget about changing scan locations or mapDirectory() for now.

If you are getting a model from a MODULE’S /models folder then you need to namespace the model with the module’s name like so:

property name=“Utility” inject=“utility@api”;

Modules recursively map all their models with a namespace. Note, this is different from the base app.
https://github.com/ColdBox/coldbox-platform/blob/master/system/web/services/ModuleService.cfc#L409

Now… if you specifically don’t want to type the “@api” bit, that’s possible but not recommended since you don’t want a module’s model to be overwriting core app models or possibly other modules’ models. Regardless, you can map whatever you want in the ModuleConfig.cfc of the module using the “binder” object. Map them the same way you would in your /config/WireBox.cfc, but prefix everything with “binder”.

moduleConfig.cfc
// This will overwrite the default namespace
binder.map( ‘utility’ ).to( ‘#moduleMapping#.models.utiity’ )

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Awesome! Thank you, Brad. I will try the @api shortly!

Hi Brad,

I just added your recommendation but still get “Variable utility is undefined.” for some reason.

in my cfc located in the modules\handlers folder, I added the following:
property name=“utility” inject=“utility@api”;
I call the utility object in a method like the following
utility.makeJSONkeyValPair(local.jsonData);

My utility.cfc is located in modules.api.models

The API ModuleConfig.cfc looks like the following:

component {

	// Module Properties
	this.title 				= "api";
	this.description 		= "This API module is designed to allow our resources to be consumed by our vendors";
	this.version			= "1.0.0";
	// If true, looks for views in the parent first, if not found, then in the module. Else vice-versa
	this.viewParentLookup 	= true;
	// If true, looks for layouts in the parent first, if not found, then in module. Else vice-versa
	this.layoutParentLookup = true;
	// Module Entry Point
	this.entryPoint			= "api";
	// Model Namespace
	this.modelNamespace		= "api";
	// CF Mapping
	//this.cfmapping			= "api";
	// Module Dependencies
	this.dependencies 		= [];

	function configure(){

		// parent settings
		parentSettings = {

		};

		// module settings - stored in modules.name.settings
		settings = {

		};

		// Layout Settings
		layoutSettings = {
			defaultLayout = ""
		};

		// datasources
		datasources = {
			contegolink = application.dsn
		};

		// SES Routes
		routes = [
			/*{
				pattern="unauthorized",
				handler="Unauthorized",
				action="index"
			},*/
			/*{
				pattern='/',
				handler='invoice',
				action='list'
			},*/
			{
				pattern="/invoice/:action/:invoiceID?",
				handler="invoice",
				action={GET='get',POST='create',OPTIONS='get',GET='view'}
			},
			{
				pattern="/invoice?",
				handler="invoice",
				action="list"
			},
			// Convention Route
			{pattern="/:handler/:action?"}
		];
		/*
		routes = [
			// Module Entry Point
			{pattern="/", handler="home",action="index"},
			// Convention Route
			{pattern="/:handler/:action?"}
		];
		*/

		// Custom Declared Points
		interceptorSettings = {
			customInterceptionPoints = ""
		};

		// Custom Declared Interceptors
		interceptors = [
		];

		// Binder Mappings
		// binder.map("Alias").to("#moduleMapping#.model.MyService");

		// The WireBox configuration structure DSL
		/*wireBox = {
			// Package scan locations
			scanLocations = ['models']
		};*/

	}

	/**
	* Fired when the module is registered and activated.
	*/
	function onLoad(){

	}

	/**
	* Fired when the module is unregistered and unloaded
	*/
	function onUnload(){

	}

}