[Coldbox 5.6.2] Instantiate a bean and populate it with the results of a query

I am refactoring some part of my code by implementing the following method in my Service object which inherits from the BaseService object.

This method is interesting because it allows, with only a few lines of code, to instantiate a bean (Extranet) and populate it at the same time by calling the function new() in the BaseService object.
For now, I can only do this by assigning values such as “ABCDE” and “CNTX” to the bean properties structure listed as argument to the new() function. Therefore, what you see below works.

However, what I want, is to pass the result of the queryExecute() to populate the bean. I tried to assign values returned by the query such as “result.extra_extranet_nm” (which I assume is the result of my query) associated to the first column of my table, but it triggers an error “result variable does not exist”.

Extranet function read(required string extranetName) {

// Returns an Extranet object populated with the result of a query

return queryExecute(
“select * from tab_extranets
where extra_extranet_nm = :extranetName”,
{
extranetName : {
value : arguments.extranetName,
cfsqltype : “cf_sql_varchar”
}
},
{datasource="#dsn.name#"})
.reduce( ( result, row ) => populator.populateFromStruct( result, row ),
new({extranetName : “ABCDE”,
extranetTenantCompanyCD : “CNTX”})
);

}

The new() function in the parent component is defined like this:

/**

  • Return a new Entity, empty or pre-populated with passed in data
  • @data Data to populate the new Entity with
    */

function new( struct data = {} ){
var modelName = getEntityName() & ( getModuleName().len() ? “@#getModuleName()#” : “” );
return populator.populateFromStruct(
target = wireBox.getInstance( modelName ),
memento = arguments.data
);
}

Currently, I am implementing my code this way, which works, but is very verbose…

public struct function read(required string extranetName) {

// I return a extranet bean populated with details of a specific application (extranet).

var qSearch = ‘’;
var objextranet = structNew();

qSearch = Super.getByName(arguments.extranetName);

if (qSearch.RecordCount) {

// if a record was returned by the query in the parent class for the extranet name key, create an instance of
// the extranet bean and return it.

objExtranet = wirebox.getInstance(“extranet”).init(
extranetName = qSearch.extra_extranet_nm,
extranetTenantCompanyCD = qSearch.extra_tenant_company_cd,
extranetLeadAccountID = qSearch.extra_extranet_lead_account_id,
extranetProcessName = qSearch.extra_extranet_process_nm,
extranetDescription = qSearch.extra_extranet_ds);

// Return the populated object

return objExtranet;

}

else {

// Return an empty object

return wirebox.getInstance(“extranet”);

}

}

It is a simple syntax problem for which I could not find any clear answer in the documentation. Could anybody point me in the right direction to solve this problem as I could save a great deal of lines of code?

returntype=“struct”?

https://docs.lucee.org/reference/tags/query.html

Even better, use Quick https://quick.ortusbooks.com/guide-1/getting-started/creating-new-entities#populate

Thanks Daemach. Yes, Quick and qb are the next re-factoring steps.

After a bit of sweat and confusion, here is the answer:

Extranet function read(required string extranetName) {

var qryResult = Super.getByName(arguments.extranetName);

return qryResult
.reduce( ( result, row ) => populator.populateFromStruct( result, row ),
new({extranetName : qryResult.extra_extranet_nm,
extranetTenantCompanyCD : qryResult.extra_tenant_company_cd,
extranetLeadAccountID : qryResult.extra_extranet_lead_account_id,
extranetProcessName : qryResult.extra_extranet_process_nm,
extranetDescription : qryResult.extra_extranet_ds})
);

}

Very few lines of code. Fast and neat. Calls a generic getByName() method in the BaseServices parent component. Returns a bean instance populated with the data returned by the query thanks to the new() function, also placed in the parent component. Results are shown in the test output attached below.