1

How do I get the mappings I have defined in application.cfc to work in other functions in other cfcs?

i.e. this.mappings["plugins"] works just fine on any page but if I try to instantiate a cfc containing a function that calls this.mappings["plugins"] - it fails.

thanks

EDIT: I'm not sure - here's what I am trying to do: In application.cfc:

this.mappings["Plugins"] = \
getDirectoryFromPath(getCurrentTemplatePath())&'Assets/Plugins';

and in stock.cfc:

<cfcomponent output="yes" > 
<cffunction name="showIndecies" access="public" output="yes" returntype="string">
<cfscript>
j = 1; 
variables.indeciesArray = ArrayNew(1); 
variables.indeciesFile = \
application.mappings["Plugins"]&'/StockMarketData/Data/indecies.csv'; 
</cfscript>
Sean Kimball
  • 4,506
  • 9
  • 42
  • 73
  • I think we need to see the rest of your function. What are you doing with the path to the CSV once you have it? Reading it, processing and returning it? You could use (as Sam notes below) cfinclude to include the CSV and then do your processing, but I would think that using cffile to read the file would be a better way to go. – Sean Coyne Jan 14 '11 at 18:53

3 Answers3

3

I think you are calling the mapping wrong. Using your definition in application.cfc:

this.mappings["plugins"]

Would then be referenced in other code by "plugins" so:

var aName = new plugins.theCFC()
var aName = createObject("component","plugins.theCFC").init()
<cfinclude template="/plugins/aFile.cfm">

HTH, if not post your code on the calling page.

Sam Farmer
  • 4,108
  • 17
  • 20
  • I'm not sure - here's what I am trying to do: in application.cfc: this.mappings["Plugins"] = getDirectoryFromPath(getCurrentTemplatePath())&'Assets/Plugins'; and in stock.cfc: j = 1; variables.indeciesArray = ArrayNew(1); variables.indeciesFile = application.mappings["Plugins"]&'/StockMarketData/Data/indecies.csv'; – Sean Kimball Jan 14 '11 at 18:41
  • I updated the original question - sorry, just getting the hang of the post syntax – Sean Kimball Jan 14 '11 at 18:46
  • That isn't really the intended use for mappings. If you just want to specify a file path to use later, you can set an application scope variable. so rather than using this.mappings you could do application.pluginsPath = getDirectoryFromPath(getCurrentTemplatePath())... then in your CFC you could reference the CFC. However, be aware that accessing the application scope from within a function is considered bad OO. It breaks encapsulation. You should instead pass that path in as an argument and call it as showIndices(pluginsPath = application.pluginsPath). – Sean Coyne Jan 14 '11 at 18:46
  • Aha, mappings don't make it into application scope. ColdFusion will just work out when you are using them by either checking if the first word in a reference is mapping for cfc or if a path starts with "/" for a cfm. So your code would be: variables.indeciesFile = '/plugins/StockMarketData/Data/indecies.csv – Sam Farmer Jan 14 '11 at 18:47
  • @Sean Coyne: It depends I think :) If Sean is intending to use cfinclude to get the csv then his solution would be fine. – Sam Farmer Jan 14 '11 at 18:48
  • True, we can't really tell what he is trying to do with it, but it just "feels" wrong to me :) – Sean Coyne Jan 14 '11 at 18:51
  • I'm actually reading it with a tag. This: variables.indeciesFile = 'Plugins/StockMarketData/Data/indecies.csv' does not work within the function. I am just trying to maintain a path that I can reference later as it may change. So this.mappings is not the way to go about it eh? hmmm. – Sean Kimball Jan 14 '11 at 18:58
  • No, its used for including files and loading CFCs. You can just use a simple application scope variable to hold it for you. You would set up this variable in your onApplicationStart method of your Application.cfc – Sean Coyne Jan 14 '11 at 18:59
  • Yeah, use a path defined as Sean Coyne said. You may want to use expandPath() to make it easier and more portable. Also, if you are using CF9, cfspreadsheet may help you reading in the csv file. – Sam Farmer Jan 14 '11 at 19:02
  • thanks guys - a quick search & replace & I managed to dig out all the this.mappings references in the application & replaced them with an application variable - of course except for within functions where it is passed as an argument. Obviously I need to review what I thought I knew about mappings. Thanks again. – Sean Kimball Jan 14 '11 at 19:19
1

Inside a CFC, of which Application.cfc is one, the "this" scope only pertains to that specific CFC. So when you are in a CFM page, that falls under the Application.cfc's jurisdiction, then the "this" scope is for the Application.cfc, but when in a CFC, its for that particular CFC.

That said, why would you need to access the mappings struct directly? If you want to use that mapping to load an object or include a file, you can just do <cfinclude template="/plugins/path/to/myfile" /> or <cfset obj = createobject("component","plugins.path.to.my.cfc") />.

What is your use case for needing to access the struct directly? Are you trying to modify it?

*edited to fix code

Sean Coyne
  • 3,864
  • 21
  • 24
1

Unless things have changed in CF9, your first mistake in the code that is defining the mapping keys without a slash "/" at the beginning of each mapping name.

You are defining the mappings as

this.mappings["plugins"] =

It should instead be

this.mappings["/plugins"] =

Notice the slash "/" in the structure key name. You must name each mapping that way.

Then you'd refer to the mappings as Sam Farmer mentioned in his comment"

Would then be referenced in other code by "plugins" so:

var aName = new plugins.theCFC()
var aName = createObject("component","plugins.theCFC").init()
<cfinclude template="/plugins/aFile.cfm">
Lostlinkpr
  • 1,453
  • 2
  • 12
  • 13