Skip to content

Using copyToScope Helper Method in Views

thofrey edited this page Apr 1, 2014 · 4 revisions

This feature was added in Mach-II 1.8+

Table of Contents

  1. Overview
  2. How copyToScope Works
  3. Getting Deeply Nested Data
  4. copyToScope Syntax
  5. Common Errors

Overview

When working on a view, it is extremely common to declare some variables at the top of the page. These variables are normally a combination of event-args, properties, and other locally declared variables. It is because of this common practice that the copyToScope helper method was introduced, in order to provide an easy way of copying multiple variables from different scopes into one specific scope for the use within the page.

How copyToScope Works

Before:

    <cfset variables.user = event.getArg("user") />
    <cfset variables.name = event.getArg("name") />
    <cfset variables.id = event.getArg("productId", 0) />
    <cfset variables.udfs = getProperty("udfs") />
    <cfset variables.i = 0 />

After:

    <cfset copyToScope("${event.user},${event.name:''},id=${event.productId:0},${properties.udfs},i=0") />

Explain the code above:

  • 'user' will be looked for in the event scope.
  • 'name' will be looked for in the event scope and will be assigned a default value of '' in case it is not defined.
  • 'productId' will be looked for in the event scope and will be assigned a default value of '0', but will be added with the name 'id'.
  • 'udfs' will be looked for in the properties scope.
  • 'i' will simply added with a value of '0'.

In the example above, all the variables will be added it to the default variables scope. By default, copyToScope will use string value after the last name as the key name in the variables scope. If you want to assign the data to a particular key, you can use this syntax:

    <cfset copyToScope("u=${event.user}") />

Notice that the user object will now be placed in variables.u.

Getting Deeply Nested Data

The copyToScope method relies on the Mach-II Expression Evaluation (EE) engine behind the scenes. This means you are not just limited to accessing data that is one level deep in the event object (ex. event.user). For example, say you need the userId that can be gotten from the user object via a getter. You can do it like this:

    <cfset copyToScope("${event.user.userId}") />

The EE assumes that once you are inside an object such as the user object in this example that is is possible to get access to data via getters. Any dot paths after the object assume the call is a getter so userId is translated to getUserId by convention. So the above example would be equal to this code in straight CFML:

    <cfset variables.userId = event.getArg("user").getUserId() />

If you need to access to data that does not follow the convention of get*() because the method name differs, you can use a special syntax. For example, let's pretend that the user object has a property that takes boolean called smart. You might follow the Java practice of having a isSmart() method (instead of a getSmart() method) and a setSmart() method. You can call that method by using the following syntax:

    <cfset copyToScope("smart=${event.user.isSmart()}") />

By default copyToScope uses the string value after the last dot as the key name, we probably do not want the key name in the variables scope as isSmart so explicitly assigned the value returned by the isSmart() method to a key of smart.

copyToScope Syntax

Attribute Required Datatype Default Description
evaluationString required list (comma delimited) [zero length string] A list of event arguments and/or mach-ii properties to copy to defined scope.
scope optional struct variables scope Scope in which to include the copied variables.

Including variables into a different scope is as simple as specifying the desired scope:

    <cfset copyToScope("${event.user},${event.name:''},id=${event.productId:0},${properties.udfs},i=0", request) />

This will include the variables into the request scope instead of the default variables scope. Be sure to pass in a reference to scope and not the name of the scope as a string.

Common Errors

  • An error like The event argument 'name' from the expression 'event.name' does not exist in the current event can occur when you try to copy an undefined variable (${event.name} in this case) in your evaluationString. Be sure that your evaluationString includes defined variables or that the variable included has a default value ${event.name:''}.
Clone this wiki locally