inject sessionstorage

I am trying to inject the session storage plugin to one of my handlers
like so:

  <cfproperty name="sUser" inject="coldbox:plugin:SessionStorage"
scope="Instance"/>

  <cffunction name="Init" output="false" returntype="Search">
     <cfreturn this>
  </cffunction>

any ideas on why this would be failing?

thanks for all of your help

Do you have autowire=true in your CFC declaration?

If you could post some more code, it would be helpful.

You aren’t calling that plugin in your sample code. Are other CFCs being autowired in the same handler? And do they work?

Jason Durham

if I take that injection out everything works, however, I want to use
the injection to reference the cb session storage in various methods,
i have updated it to this

  <cfproperty name="SessionStorage"
inject="coldbox:plugin:SessionStorage" scope="Instance"/>

  <cfscript>
    TestMe=Instance.SessionStorage;
  </cfscript>

which should work, however, it fails with:

Application Execution Exception
Error Type: Expression : [N/A]
Error Messages: Element SESSIONSTORAGE is undefined in INSTANCE.

Hi,

Coldbox actually create component then inject dependencies then
execute onDIComplete() method.

1: Create object.
2: Inject dependencies
3: if onDIComplete() method exists then execute

So if you put your code inside of onDiComplete() method then it will
be initialed
function void onDIComplete(){
        <cfscript>
                TestMe=Instance.SessionStorage;
        </cfscript>
}

More detail here
http://wiki.coldbox.org/wiki/Interceptors:Autowire.cfm#5._Complete_DI_Method_Name

Thanks
Sana

Are you reiniting after making changes?

- Gabriel

yes, I reinit every time.

i am trying to reference the data from the plugin in the sample code -
in the sessionstorage cb container I have a few structs that I want to
have access to

  <cfproperty name="SessionStorage"
inject="coldbox:plugin:SessionStorage" scope="Instance"/>

  <cfscript>
    TestMe=Instance;
  </cfscript>

  <cffunction name="Init" output="false" returntype="Search">
     <cfreturn this>
  </cffunction>

basically I just want to have an instance point to the entire session
struct itself so I can access each of the cb storage session vars

Can you copy/paste a real example? The first code snippet didn’t call SessionStorage. The 2nd code snippet was solved by Sana (you were setting a variable before dependencies were injected). The 3rd snipped doesn’t call SessionStorage.

This code should work (baring any typos)…

If you want to use the plugin at the time of instantiation, you’re best option is to add onDIComplete() as Sana suggested.

Jason Durham

ok, i think the problem may be one handler calling an event on another
handler

my log in handler processes the log in correctly than runs an event to
show the search page like so:

//open the search view
setNextEvent(event="Mall.Search.dspSearch");

from the search handler, if I remove the injection everything works,
but I want to use the injection to save code as multiple functions
will need to use the vars. regardless of how I setup the examples
above it keeps failing saying the controller "Variable CONTROLLER is
undefined."

i think I may have a larger issue here as I have managed to screw up
even my first page of my application

user login handler:

<cfcomponent name="Login"
extends="mapping.handlers.ApplicationHandlerHelper" output="false"
autowire="true">

<!------------------------------------------- CONSTRUCTOR
-------------------------------------------->

  <cffunction name="Init" output="false" returntype="Login">
     <cfreturn this>
  </cffunction>

<!----------------------------------------- IMPLICIT EVENTS
------------------------------------------>

  <!--- preHandler --->
  <cffunction name="preHandler" returntype="void" output="false"
hint="Executes before any event in this handler">
    <cfargument name="event" required="true">
    <cfargument name="action" hint="The intercepted action"/>
    <cfscript>
      var rc = event.getCollection();
    </cfscript>
  </cffunction>

<!------------------------------------------- PUBLIC EVENTS
------------------------------------------>

  <!---

ok, made a little progress here, still drawing straws,

now I got pass the first error but it blows up at
"ChkUserName=runEvent(event='User.Model.User.ChkUser',private=false);"

ideas?

thank you all for your continued help

<cfcomponent name="Login"
extends="mapping.handlers.ApplicationHandlerHelper" output="false"
autowire="true">

<!------------------------------------------- CONSTRUCTOR
-------------------------------------------->

  <cfproperty name="AppShared" inject="Coldbox:Setting:AppShared"
scope="Instance"/>

  <cffunction name="Init" output="false" returntype="Login">
     <cfreturn this>
  </cffunction>

<!----------------------------------------- IMPLICIT EVENTS
------------------------------------------>

  <!--- preHandler --->
  <cffunction name="preHandler" returntype="void" output="false"
hint="Executes before any event in this handler">
    <cfargument name="event" required="true">
    <cfargument name="action" hint="The intercepted action"/>
    <cfscript>
      var rc = event.getCollection();
    </cfscript>
  </cffunction>

<!------------------------------------------- PUBLIC EVENTS
------------------------------------------>

  <!---

Do you really have a handler called User.Model.User with a method
called ChkUser in it?

It looks like you are really trying to execute a method in your model,
not really run another event. And that would really be the right thing
to do. Checking for validity of a user is usually something you do in
a service layer, not an independent event. If that is true in your
case, you want to get rid of RunEvent and instead just call your
model.

You might do something like:

var UserService = getModel("User.Model.User");
var ChkUserName = UserService.ChkUser(argumentCollection=rc);

Does that help?

the
ChkUserName=runEvent(event='User.Model.User.ChkUser',private=false);
actually calls a different handler class designed to talk to the
model, its just placed inside of a directory called Model identifying
that its used to communicate with the model

thoughts?

Personally, I'd say that your handler should talk to a Service layer
in your model which then takes care of getting data and what not. I
don't really see any advantage to going through another event because
you don't want to really expose that event out to the rest of the
world, it doesn't really have public function, it is just a service
layer for your model.

More to the point of trying to figure out what is causing your actual
error...what version of ColdBox are you using? The syntax you are
using for dependency injection in your User handler seems to have some
confusion between pre-3.0 and post-3.0

This line: <cfproperty name="User"inject="Model" scope="Instance"/>
is using the new syntax (inject="Model") but also trying to use an
artificial scope="Instance". I don't believe that putting the result
of the injection into a fake scope is supported any longer. It
wouldn't have worked in your code anyway because you never called
Instance = StructNew() anywhere.

I'd see about putting your code into a test area and trying to build
something simple with DI. Create a UserService that has your ChkUser
function and whatnot and put it in a Model folder. In your
UserService you can use the getModel function to create your User
beans from your model and then in your Login handler you can us the
cfproperty model injection to put make your UserService available to
the handler. See if that works in the simple cases and then build up
from there.

Judah

ok i reworked that into the following handler:

<cfcomponent name="Login"
extends="mapping.handlers.ApplicationHandlerHelper" output="false"
autowire="true">

<!------------------------------------------- CONSTRUCTOR
-------------------------------------------->

  <cfproperty name="AppShared" inject="Coldbox:Setting:AppShared"
scope="Instance"/>
  <cfproperty
name="SessionStorage"inject="coldbox:plugin:SessionStorage"
scope="Instance"/>
  <cfproperty name="MessageBox"inject="coldbox:plugin:MessageBox"
scope="Instance"/>
  <cfproperty name="User"inject="Model" scope="Instance"/>
  <cfproperty name="LogMe"inject="Model" scope="Instance"/>
  <cfscript>
    Instance = StructNew();
  </cfscript>
  <cffunction name="Init" output="false" returntype="Login">
     <cfreturn this>
  </cffunction>

<!----------------------------------------- IMPLICIT EVENTS
------------------------------------------>

  <!--- preHandler --->
  <cffunction name="preHandler" returntype="void" output="false"
hint="Executes before any event in this handler">
    <cfargument name="event" required="true">
    <cfargument name="action" hint="The intercepted action"/>
    <cfscript>
      var rc = event.getCollection();
    </cfscript>
  </cffunction>

<!------------------------------------------- PUBLIC EVENTS
------------------------------------------>

  <!---

I'm still seeing a bunch of: scope="instance" stuff in there. I also
don't see why there is the onRequest and preHandler functions that
fetch the request collection but never do anything with them. It also
looks like you are using runEvent after determining that it was a bad
login and that you need to get them back to the login page. I'd guess
that you'd want to do a setNextEvent to redirect them to it. I don't
think that persist works with runEvent anyway.

What are the actual errors you are getting at this point?

I'd really still start with some sample, pared down code from the
examples and then try to build up to the basics of what you are trying
to do...call a service layer that you've injected with WireBox and use
the SessionStorage that you've injected with WireBox as well.

Cheers and keep up the spirits, once you get it sorted out the first
time or two it gets a lot easier.
Judah

ok I have reduced all of these items as instructed, however, I keep
getting the same error when the from submits with an invalid user

"Application Execution Exception
Error Type: Expression : [N/A]
Error Messages: Variable CONTROLLER is undefined."

<cfcomponent name="Login"
extends="mapping.handlers.ApplicationHandlerHelper" output="false"
autowire="true">

<!------------------------------------------- CONSTRUCTOR
-------------------------------------------->

  <cfproperty name="AppShared" inject="Coldbox:Setting:AppShared"/>
  <cfproperty
name="SessionStorage"inject="coldbox:plugin:SessionStorage"/>
  <cfproperty name="MessageBox"inject="coldbox:plugin:MessageBox"/>
  <cfproperty name="User"inject="Model"/>
  <cfproperty name="LogMe"inject="Model"/>

  <cffunction name="Init" output="false" returntype="Login">
     <cfreturn this>
  </cffunction>

<!----------------------------------------- IMPLICIT EVENTS
------------------------------------------>

<!------------------------------------------- PUBLIC EVENTS
------------------------------------------>

  <!---

How are you calling the page on the very first try? Is it
index.cfm?event=Login.dspLogin The reason I ask is that you are
doing a redirect on a validation failure to User.Login.dspLogin and
if this handler is up at the top level of your handlers structure it
should just be Login.dspLogin with no User. prepended.

Is there a way you could zip up your code and put it somewhere that I
could download it and try to run it locally?

Cheers,
Judah

the dsplogin function is the default function that gets called when
the user comes to the app to log in, from that point i use
setNextEvent to go to the various other methods

i could not zip it up because the model would not work as it its tied
to our sql server db for user information

the main.cfc :

<cfcomponent output="false">

<!------------------------------------------- GLOBAL IMPLICIT EVENTS
ONLY ------------------------------------------>
<!--- In order for these events to fire, you must declare them in the
coldbox.xml.cfm --->

  <cffunction name="index" returntype="void" output="false">
    <cfargument name="event" required="true">
    <cfset setNextEvent(getSetting('DefaultEvent'))>
  </cffunction>

  <cffunction name="onAppInit" returntype="void" output="false">
    <cfargument name="event" required="true">
    <cfscript>

    </cfscript>
  </cffunction>

  <cffunction name="onAppShutDown" returntype="void" output="false">
    <cfargument name="event" required="true">
    <cfscript>
      GetPlugin('SessionStorage').removeStorage();
    </cfscript>
  </cffunction>

  <cffunction name="onRequestStart" returntype="void" output="false">
    <cfargument name="event" required="true">
    <cfscript>
      var rc = event.getCollection();
      //setup the session storage containers
      HandleMallfinderSessionStorage(event=event);

      //Temporary Development Variable
      GetPlugin('SessionStorage').setVar('Test',"");
    </cfscript>
  </cffunction>

  <cffunction name="onRequestEnd" returntype="void" output="false">
    <cfargument name="event" required="true">
    <cfscript>
      var rc = event.getCollection();

    </cfscript>
  </cffunction>

  <cffunction name="onSessionStart" returntype="void" output="false">
    <cfargument name="event" required="true">
    <cfscript>

    </cfscript>
  </cffunction>

  <cffunction name="onSessionEnd" returntype="void" output="false">
    <cfargument name="event" required="true">
    <cfset var sessionScope = event.getValue("sessionReference")>
    <cfset var applicationScope =
event.getValue("applicationReference")>
    <cfscript>
      GetPlugin('sessionstorage').removeStorage();
    </cfscript>
  </cffunction>

  <cffunction name="onException" returntype="void" output="false">
    <cfargument name="event" required="true">
    <cfscript>
      //Grab Exception From request collection, placed by ColdBox, Place
exception handler below:
      var exceptionBean = event.getValue("ExceptionBean");

    </cfscript>
  </cffunction>

  <cffunction name="onMissingTemplate" returntype="void"
output="false">
    <cfargument name="event" required="true">
    <cfscript>
      //Grab missingTemplate From request collection, placed by ColdBox
      var missingTemplate = event.getValue("missingTemplate");

    </cfscript>
  </cffunction>

<!------------------------------------------- PRIVATE EVENTS
------------------------------------------>

  <cffunction name="HandleMallfinderSessionStorage" returntype="void"
output="false" access="private">
    <cfargument name="event" required="true">
    <cfscript>
      var rc = event.getCollection();
      //get current tabs, breadcrumbs, and navigation
      var sSessionStorage=GetPlugin('SessionStorage').getStorage();
      //have the tabs been added to the cb storage container
      if(
        (Not IsDefined("sSessionStorage.sTabs")) OR
        (IsDefined("sSessionStorage.sTabs") And Not
IsQuery(sSessionStorage.sTabs))
      ){
        //build default tabs and add it to the cb storage container
  
GetPlugin('SessionStorage').setVar('sTabs',runEvent(event='layouts.Tabs.GetTabData',private=false));
      };
      //has the default breadcrumb been added to the cb storage container
      if(
        (Not IsDefined("sSessionStorage.sBreadCrumbs")) OR
        (IsDefined("sSessionStorage.sBreadCrumbs") And Not
IsArray(sSessionStorage.sBreadCrumbs)) OR
        (IsDefined("sSessionStorage.sBreadCrumbs") And
IsArray(sSessionStorage.sBreadCrumbs) And
ArrayLen(sSessionStorage.sBreadCrumbs) Eq 0)
      ){
        //build default breadcrumbs and add it to the cb storage container
  
GetPlugin('SessionStorage').setVar('sBreadCrumbs',runEvent(event='layouts.BreadCrumbs.GetBreadCrumbData',private=false));
      };
      //has the default navigation been added to the cb storage container
      if(
        (Not IsDefined("sSessionStorage.sNavigation")) OR
        (IsDefined("sSessionStorage.sNavigation") And Not
IsArray(sSessionStorage.sNavigation)) OR
        (IsDefined("sSessionStorage.sNavigation") And
IsArray(sSessionStorage.sNavigation) And
ArrayLen(sSessionStorage.sNavigation) Eq 0)
      ){
        //build default breadcrumbs and add it to the cb storage container
  
GetPlugin('SessionStorage').setVar('sNavigation',runEvent(event='layouts.Navigation.GetNavigation',private=false));
      };
    </cfscript>
  </cffunction>

</cfcomponent>