You need to sign in to do that
Don't have an account?
Help with Loop Construction
Hi,
I need a hand building this loop for the following scenario. I have a grandparent that is passed to a page via query string, this grandparent refers to multiple parents, and those multiple parents each have multiple children
I want to yield this:
grandparent 1
+++parent 1
++++++child a
++++++child b
+++parent 2
++++++child c
++++++child d
The loop in the controller is confounding me.
parents = [SELECT id,Name FROM Parent__c WHERE Grandparent__c=:grandparentId]; for(Parent__c parents1:parents) { // fetch the values by SOQL on the basis of parent id children=[select id,Name FROM Child__c WHERE Parent__c=:parents1.id]; system.debug('size'+ parents.size()); system.debug('>>>>>>>>>>>>>>>>>'); children1.addall(children); }
This is clearly incorrect. It is going to build a list of ALL the parents of the grandparent and then take ALL of their children and store them in children1 variable. This won't accomplish the tree-type view I want, it will instead show this:
grandparent 1
+++parent 1
++++++child a
++++++child b
++++++child c
++++++child d
+++parent 2
++++++child a
++++++child b
++++++child c
++++++child d
How should I build this loop?
That post is from 2009. Since then, they've made a couple of improvements. I just made a working mockup, which I will now copy directly here:
Here is a sample output:
All Answers
SOQL inside loop. Bad design. You need to start from the other direction. Try this:
All of this code lets you do the following:
Basically, we create a named keyset of grandparents and their associated parents, which in turn has a named keyset of each parent and their children. The three maps are used to pull out additional information as you desire. This isn't necessary the "most efficient" method (you could do this in one really big query and just map the sobjects directly), but is probably marginally easier to read and understand.
Edit: Corrected some typos.
Thank you sfdcfox, you are a true guru!
I have two questions as I try this.
1) c.Parent__c below should be child.Parent__c, correct?
2) This block returns:
"Save error: Method does not exist or incorrect signature: [MAP<Id,MAP<Id,LIST<Id>>>].put(Id)"
1) Right. I was just typing on the fly, but you spotted it. Good catch.
2) Should have ",new map<id,id>()" after the "__c" on the middle line.
I updated my prior reply with the suggested changes.
Hm,
"Save error: Incompatible value type MAP<Id,Id> for MAP<Id,MAP<Id,LIST<Id>>>" with the new change here:
Sorry, should have been map<id,list<id>> instead of just map<id,id>. Try that (edited above).
Maybe I'm declaring it incorrectly, but now I get this error:
"Save error: Method does not exist or incorrect signature: [MAP<Id,MAP<Id,LIST<Id>>>].contains(Id)"
Note: http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_map.htm doesn't list "contains" as a method for maps, did you mean to put ContainsKey instead?
Assuming that is all the controller needs, my page is not displaying any of the data eventhough I am fetching the values in the controller.
I found many threads like this: http://boards.developerforce.com/t5/Visualforce-Development/Can-Map-collection-be-Apex-Repeat-tag-s-value/td-p/155442 saying that you can't directly display maps in repeat tags? Do I have to build a list?
That post is from 2009. Since then, they've made a couple of improvements. I just made a working mockup, which I will now copy directly here:
Here is a sample output:
Greatly appreciated!!! Neat trick with the pre formatted text tag, I hadn't seen that used before.
I was just too lazy to use real tags, so I faked it for appearances. I don't think I've ever seen "pre" used in any actual Visualforce page since it is trivially difficult to accurately control the output of whitespace in a Visualforce page (even my list is screwed up, as an example).
It works wonderfully. You are my hero right now, sfdcfox
How would you most elegantly expand this case to cover a second type of children, say, foster children?
Not every parent would necessarily have foster children, just as every parent wouldnt necessarily have regular children, so the parent map would have to be ALL the parents related to the grandparent instead and then only display children when they exist?
This controller works. I'm sure there are ways to condense and clean this up but its pretty easy to understand this way. I'm filling in two trees for my two child types, incomes and contacts with the SAME parents and grandparent maps
The only maps that differ are the child maps