I am new to ColdBox (and mvc in general) and have been trying to sort this out myself, to no avail. A finding function works fine on our procedural site, and I am trying to get my feet wet with switching it to mvc, bit by bit.
On my mvc test site, I have a query that, when executed on my local machine, correctly returns the expected elements. But when it's run on the live site, it repeats the first element for however many elements are in the returned array.
Local machine: ColdBox 4.3, Lucee 4.5.5, MySQL 5.6.37, PHPMyAdmin 4.4.15
Live: ColdBox 4.3, ACF 2016, MySQL 5.7, PHPMyAdmin 4.6.6
Here is the function in my CFC:
function getMilestonesByDate(required string pickedMonth='', required string pickedDay='') {
transaction {
queryMilestonesByDate = queryExecute("
SELECT tbl_milestones.ID as milestoneID, tbl_milestones.event, tbl_milestones.date
FROM tbl_milestones
WHERE MONTH(tbl_milestones.date) = :pickedMonth AND DAY(tbl_milestones.date) = :pickedDay AND YEAR(tbl_milestones.date) != 1111
ORDER BY tbl_milestones.date ASC
", {
pickedMonth: {value: arguments.pickedMonth, cfsqltype: "cf_sql_varchar"},
pickedDay: {value: arguments.pickedDay, cfsqltype: "cf_sql_varchar"}
}
);
}
milestonesByDate = arrayNew(1);
for (row in queryMilestonesByDate) {
returnStruct = StructNew();
returnStruct["milestoneID"] = queryMilestonesByDate.milestoneID;
returnStruct["event"] = queryMilestonesByDate.event;
returnStruct["date"] = dateFormat(queryMilestonesByDate.date, "full");
arrayAppend(milestonesByDate, returnStruct);
}
return serializeJSON(milestonesByDate);
}
Again, this works fine locally. For example, it will show two different milestones for December 26 -- one in 1986 and one in 1995. But on the live site, it will show the 1986 milestone twice.
However, running just the SQL in PHPMyAdmin on the live site works as expected:
SELECT tbl_milestones.ID as milestoneID, tbl_milestones.event, tbl_milestones.date
FROM tbl_milestones
WHERE MONTH(tbl_milestones.date) = '12' AND DAY(tbl_milestones.date) = '26' AND YEAR(tbl_milestones.date) != 1111
ORDER BY tbl_milestones.date ASC
So the query seems to be okay. But something is being munged somewhere, and I cannot figure it out. If it helps, here is the call to the function in my event handler:
function showMilestonesByDate( event, rc, prc ) {
prc.milestonesByDate = milestoneModel.getMilestonesByDate(pickedMonth,pickedDay);
event.renderData( type="json", data=prc.milestonesByDate );
}
The values for picked month and picked day come from a jQuery UI datepicker. I can post that code if anybody thinks it will be helpful. But just dumping out the query results from hardcoded values on a test page shows the same issue, regardless of whether the datepicker is used or even if it is present on the page.
Note that this all works fine on our procedural site, but I am having a tough time switching things to mvc and would appreciate any tips or suggestions on where I am going wrong! Thank you all in advance!
UPDATE: here is a dump of prc.milestonesByDate from the local site:
[{"date":"Friday, December 26, 1986","event":"First flight of Russian Mil Mi-34","milestoneID":435},{"date":"Tuesday, December 26, 1995","event":"First flight of Indian Navy's HAL Dhruv (Protoype PT4)","milestoneID":428}]
And the same thing from live:
[{"date":"Friday, December 26, 1986","milestoneID":435,"event":"First flight of Russian Mil Mi-34"},{"date":"Friday, December 26, 1986","milestoneID":435,"event":"First flight of Russian Mil Mi-34"}]
The issue happening here is that the for
loop for the query in ACF and Lucee behaves a bit different.
I am not sure about the reason for this. But what I observed is that the for
loop in Lucee works like the <cfloop query="">
. But it is not the case in ACF.
In ACF you need to use the variable row
inside the loop instead of using queryMilestonesByDate
.
for (row in queryMilestonesByDate) {
returnStruct = StructNew();
returnStruct["milestoneID"] = queryMilestonesByDate.milestoneID;
returnStruct["event"] = queryMilestonesByDate.event;
returnStruct["date"] = dateFormat(queryMilestonesByDate.date, "full");
arrayAppend(milestonesByDate, returnStruct);
}
So, in order for the loop to work in both ACF and Lucee you can change it as the following (which I believe is the correct approach since you are using for (row in queryMilestonesByDate)
).
for (row in queryMilestonesByDate) {
returnStruct = StructNew();
returnStruct["milestoneID"] = row.milestoneID;
returnStruct["event"] = row.event;
returnStruct["date"] = dateFormat(row.date, "full");
arrayAppend(milestonesByDate, returnStruct);
}
Examples about how it works.