• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Stumped - Variable exists, then does not.

Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Whew!  This is a new one on me!  One of those times CF simply isn't making any logical sense to how I understand it.  I've even gone through CF10 Application Server and IIS Admin service restarts and still getting the same problem.

In short, I have a template component which has a variable called rawCode.  It is the current request's generated HTML that is to be output to the buffer.  I am inside a method inside the template component, and I dump: THIS.rawCode.

Sure enough, it contains what I expect.

I then call a method from within this method (that method exists in the template component as well)

<cfinvoke component="#THIS#" method="writeOutputToBuffer">

All that method does right now is:

<cfoutput>#THIS.rawOutput#</cfoutput>

But guess what?  At that point, there's nothing!  Nothing is presented to the user.  I had it dump THIS.rawCode and BOOM, the rawCode is there and populated with what I wante returned to the user.  Has anyone seen something like this before?  I'm sure there's some rare thing I'm doing wrong here, like some recently unknown "CF10 can only support referencing a variable 20 times per request" rule or something as crazy.

Views

10.9K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Advocate , Oct 24, 2012 Oct 24, 2012

Does writeOutputToBuffer() have output="true"?

Jason

Votes

Translate

Translate
Guide ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

You say "THIS.rawCode" at the top of your post, but refer to "THIS.rawOutput" in the method call.

-Carl V.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Good catch.  Sorry, they all say the same thing.  'THIS.rawCode'.  Sorry 'bout that.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Show us more code. What does this "template component" look like?  How does it get populated with the "rawCode". How are you invoking the Component? 

Jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Dunno.  But two things.

  1. If you're within the same CFC, you don't need to specify the COMPONENT attribute of the <cfinvoke> tag.  Perhaps because you are passing it THIS, it's doing something other than you expect?  Not sure.
  2. For pity's sake, don't use <cfinvoke>.  Just go <cfset writeOutputToBuffer()>

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

@12Robots—

Man, it's such an extensive setup I have.  I'll try to provide some code without giving all the exta.

By default, the code is created in the template.cfc's pseudo constructor:

<cfparam name="THIS.rawCode" type="string" default="">

In the onRequest(), we create an instances of the template component by doing the following: (this component extends the root application.cfc)

<cfset REQUEST.template = createObject( 'component', 'www.app.coms.template' )>

We then call a method in the REQUEST.template component to start creating the output code:

<cfinvoke component="#REQUEST.template#" method="generateRequestOutput">

It goes through many steps, populating the THIS.rawCode with content until we get to the very end of the generateRequestOutput() method.  There are 2 closing functions:

processTemplateVars() - Before AND after this method is called, we can dump THIS.rawCode and we see what we expect.  The last function,

writeOutputToBuffer() - When I do the dump of THIS.rawCode in that function, I get nothing.  But when it returns back to the generateRequestOutput() after the writeOutputToBuffer(), and I dump it, it DOES exist.

That's where I'm confused.

@Adam Cameron—

1. Cool; didn't know that.  CF must assume a local invoke when the component is not specified.  I'll try to remove that.

2. Really?  I love how you can use argument names as attributes in a <CFINVOKE>.  I hate writing like writeOutputToBuffer( arg1, arg2, arg3 ).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Scrap some of that.

It seems after I call the writeOutputToBuffer() method and return back to the generateRequestContent() method, outputing or dumping the THIS.rawCode results in NOTHING being there.  The variable just seems to empty out somewhere.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Does writeOutputToBuffer() have output="true"?

Jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

cfinvoke is an evil beast that serves a dark master. It is of occasional use, but in 99 out of 96 cases, it is ugly, ugly, and ugly.

You know you can name variables the other way too, right?

writeOutputToBuffer( arg1=arg1, arg1=arg2, arg1=arg3 )

jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

No I did not know that, 12Robots.

You guys are like goldmines of cool info.  Well if I can write it as <cfset functionName( argName=value, argName=value, etc.) then I'll try to go through and get rid of the invokes in my setup.

As for the writeOutputToBuffer(), the output is set to false.  To my understanding (which can be wrong), when true, the function is processed as if wrapped in a CFOUTPUT (and vice versa for false)  I have:

<cfoutput>#THIS.rawCode#</cfoutput>

in the function with output=false in the method hoping that would suffice to get that content to the buffer, but there's just nothing.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

To my understanding (which can be wrong), when true, the function is processed as if wrapped in a CFOUTPUT (and vice versa for false)  I have:

Nope.  The OUTPUT attribute looks like it's boolean, but it's actually got three distinct states.

TRUE = as if the code within is wrapped in <cfoutput> tags

FALSE = as if the code within is wrapped in <cfsilent> tags

[not specified at all] = just like any other CFML code: text will output, CF expressions will be processed if if surrounded in pound signs and <cfoutput> tags.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

So as it is in the documentation.  Wow.  ColdFusion documentation that's RIGHT.  Who'd have guessed it, eh?    *elbows ribbingly*

Good deal.  So what I was doing was operating as <CFSILENT>  But even as such, wrapping my code in <CFOUTPUT> should have still output it to the buffer right?  Gotta find out why this thing is disappearing.

I've been testing it and it seems if I CFABORT in the writeOutputToBuffer() after CFOUTPUT-ing it, it shows up!..... What the funk 'n wagnalls is going on here?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Aegis Kleais wrote:

But even as such, wrapping my code in <CFOUTPUT> should have still output it to the buffer right?

No, that's not right.  Why don't you try it.  You could have typed output="true" a thousand times since I suggested it, instead you keep arguing back and forth. Try it.

Aegis Kleais wrote:

I've been testing it and it seems if I CFABORT in the writeOutputToBuffer() after CFOUTPUT-ing it, it shows up!..... What the funk 'n wagnalls is going on here?

<cfabort> flushes the output buffer (or some techno jargon like that) and so it does nto matter if output="true".  No matter where you are (cfsilent, etc) if you do a dump + abort it will always show up.

Jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Jason

You should step back a little at this point.  I'm not sure if this was on my side or not, and I'm a proponent in the belief that communication through text-only mediums can often lead to miscues and inferred inflection of emotion that isn't there, but nobody is arguing with you.

My application.cfc has the OUTPUT set to FALSE, and my onRequestStart() has the OUTPUT set to FALSE, and in it, I just put

<cfoutput>Hello</cfoutput>

<cfabort>

And sure enough, code was output to the user.  There's obviously a misunderstanding here, as you're very obviously skilled in ColdFusion, but try not to read my posts in any preconceived argumentative tone; because there isn't one.  Thanks to what you've just stated, you helped me understand that the <cfabort> was forcibly flushing the buffer, so the way I had envisioned how things were working was faulty due to <cfabort> forcing the content rendering.  Learned another new thing;  During my development, I used cfabort so often in halting progress, that I never thought about what it was doing to the content generated already or how that was affected by the component and function output attributes.

I'm always appreciative of people who help me understand these things; and as I've shown in previous posts in this thread, I'm not just waiting for an answer; I am still trying things locally in the meantime.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

With the info Jason gave me, it now makes sense as to why the code exists while I am performing a CFABORT.

Let me state the following in hopes it might help.  In the template.cfc I defined the THIS-scoped variables not via <CFSET> but via <CFPARAM>, ie:

<cfparam name="THIS.var1" type="string" default="value">

rather than

<cfset THIS.var1 = 'value'>

Usually, I use <cfparam> while in functions after declaring the local scope like:

<cfset var LOCAL = {}>

<cfparam name="LOCAL.varName" type="string" default="value">

I'm just stating this in hopes that using cfparam in the component's pseudo-constructor isn't a problem (seemed to work fine for application.cfc, but I'm just stating it nonetheless)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

So did you add output="true" to writeOutputToBuffer() or not?  How about you try what people suggest, and then if it works you ask why? 

I'm glad that you think that this is a great way for you to learn, but you have to understand that when you don't even try what is suggested then you only serve to frustrate those who are trying to help you.

To my knowledge you still have not tried the 2 second fix that I suggested. I'm done trying to help you.

Stepping all the way back,

Jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Jason

I've tried being respectful, I've even made mention that I did what you said and got the result you said I'd get as verification that I comprehended a new concept.

The last thing I need is this attitude.  The forum doesn't have an ignore feature, otherwise you'd rightfully be on it.  But if this is how you help people on the forums, then go pound some dirt, because millions of teachers before you have been able to get someone to comprehend something without the pissant attitude that comes with your posts.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

And where did you tell me that you added output="true" to your function? And where did you tell me that that worked and that your problem was solved?

I missed it amongst all the other learning.

Jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Listen, I'm sorry that I got so upset. I strive to help people and I got frustrated. I apologize for that.

In all seriousness, I suggested several times that you try adding output="true" to your function and I can see no where in this thread where you actually said you tried that. I see where you tell me that it is set to false, but I don't see where you tell me that you tried my suggestion. That is frustrating.  I tried helping you and it just seemed that you were repeatedly ignoring my advice. I understand that you don't just want an answer and that you want to learn. I respect that. But couldn't you try what I suggested, report back and ask questions about it?  I'm more than happy to answer questions. But when I feel like my advice is being completely ignored, I tend to get a little irritated. I suspect that I am not alone in that feeling.

Jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Don't assume everyone is adept as you might be to learning things.  I don't like having it called to light because it's as frustrating for me as I'm sure it is for others, but I don't learn the same way others do.  I'm the type of person, when learning something, has to take things step by step and comprehend them at each step, or I lose focus and the concept is lost completely to me.

Secondly, due to how rare it is, I want to commend you on at least being man enough to apologize.  I don't mean to cause anyone frustration, and if I do, I'm sorry for doing so.

I have set the output on the onRequest(), generateRequestContent() and writeOutputToBuffer() all to TRUE for the time being.

In writeOutputToBuffer() I am merely doing a:

<cfoutput>#THIS.rawCode#</cfoutput>

And I have removed all <CFABORT> tags.  Upon running a request, I do not see any output on screen nor in the view source.

** UPDATE ** I might have another temporary issue that is skewing my results, so don't take what I just said to heart yet.  I was going through my code changing CFINVOKE's to <cfset path.to.functionName( arg='value' ) as suggested by Adam, and I noticed that when I request my hostname, I don't see it redirecting to the login page, like it should.

Let me see if I can fix THAT issue, and then see if having turned all those OUTPUT to true made a difference.  I'll let you know...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Cool. Thank you for accepting my apology.

Aegis Kleais wrote:

** UPDATE ** I might have another temporary issue that is skewing my results, so don't take what I just said to heart yet.  I was going through my code changing CFINVOKE's to <cfset path.to.functionName( arg='value' ) as suggested by Adam, and I noticed that when I request my hostname, I don't see it redirecting to the login page, like it should.

As Jason suggested

Jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

Ooh!  Sorry man.  I didn't mean to mix you two up.  You're right.  YOU were the one telling me how evil the CFINVOKE was.  Something about a dark master if I recall.

And hey!  Once I resolved the snafu on my part as I was going through and changing those invokes over, my page started redirecting to the login, the template component got called AND THE CODE DUMPED TO THE BUFFER!!!

Jason, if you were local, I'd buy you a Steak Dinner and some beers.  I learned a lot of things here; how <CFABORT> dumps generated code to the buffer, how to properly determine the OUTPUT attribute on my components and functions.  That seems to be it!  The onRequest had a output='true' but both my generateRequestContent() and writeOutputToBuffer() had output='false' under the bad understanding that using <cfoutput> would override that.  (I now know better, since output='false' is like using a <CFSILENT> and when not aborting, a silent tag keeps all output out of the buffer (which was why the code wasn't showing)

Jason, you the man!  My thanks for helping me comprehend ColdFusion.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 24, 2012 Oct 24, 2012

Copy link to clipboard

Copied

You're welcome.  Glad it worked out.

jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 25, 2012 Oct 25, 2012

Copy link to clipboard

Copied

I was going through my code changing CFINVOKE's to <cfset path.to.functionName( arg='value' ) as suggested by Adam, and I noticed that when I request my hostname, I don't see it redirecting to the login page, like it should.

As Jason suggested

Whilst we're splitting hairs (and, seriously, I don't care), but it was me who suggsted getting rid of the <cfinvoke> tags in favour of just using method calls.  You (Jason) blathered on about evil and that sort of nonsense, but did clarify the name=value pairing thing.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Oct 25, 2012 Oct 25, 2012

Copy link to clipboard

Copied

Of course, you are aright. I thought about that last night as I was trying to sleep. You beat me to the correction.

Jason

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation