2
{"methods":[[{"p_id":"v1","offline":false,}],[{"p_id":"v2","offline":true,}]]}

The above is my JSON payload. I am making use of nested Iterate mediators to fetch the values of p_id and v1. I am able to fetch the values successfully, but the logs outside the first iterate mediator are not getting printed.

Following is my code:

<iterate expression="json-eval($.methods)" id="iterate-over-Methods">
    <target>
        <sequence>
            <iterate expression="json-eval($)" id="2nd-iteration">
                <target>
                    <sequence>
                        <filter regex="false" source="json-eval($.offline)">
                            <then>
                                <property expression="json-eval($.p_id)" name="p-id" scope="default" type="STRING"/>
                                <log>
                                    <property expression="$ctx:p-id" name="p-id-set"/>
                                </log>
                            </then>
                            <else>
                                <log>
                                    <property name="p-id-set" value="Provider ID already set"/>
                                </log>
                            </else>
                        </filter>

                        <log>
                            <property name="status-1" value="Inside 1st iteration" />
                        </log>
                    </sequence>
                </target>
            </iterate>
            <log>
                <property name="status-2" value="Inside 2nd iteration" />
            </log>
        </sequence>
    </target>
</iterate>

Is the code going into some infinite loop that it is not coming out? How can I handle this? Thanks in advance..

ycr
  • 12,828
  • 2
  • 25
  • 45
Ruby
  • 368
  • 1
  • 9
  • Why do you need two loops here? Why can't you use `json-eval($.methods)` in your second loop? – ycr Sep 12 '22 at 11:17
  • If you observe the json payload, it is an array inside another array – Ruby Sep 12 '22 at 11:27
  • Do you want to just access these objects `{"p_id":"v1","offline":false,}`? Also, do you intend to use the `Call` or `Send` mediator within the Iterate mediator? Also if your full payload is different from the one yo shared I would suggest sharing a complete payload. (The one you shared above is not a valid JSON payload) – ycr Sep 12 '22 at 11:50
  • If you share more details we can probably help out. You might be able to save yourself a lot of trouble by using the Foreach mediator instead of the iterate mediator. Currently you are missing Aggregate mediators that you need with the iterate mediators, with Foreach you don't need that. – ophychius Sep 12 '22 at 11:55
  • The json-payoad that I shared is a part of the API response I get from an external System. And as I am making use of multiple API calls, I think for-each mediator would not help out. Setting continue-parent="true" helped me out in this. – Ruby Sep 12 '22 at 12:21

1 Answers1

3

From the information you provided I think you can use a single Iterator here.(But this really depends on your full usecase). Here is a sample with a single Iterate Mediator.

<iterate expression="json-eval($.methods)" id="pl-iterator">
    <target>
        <sequence>
            <property expression="json-eval($[0].p_id)" name="p-id" scope="default" type="STRING"/>
            <log level="full">
               <property expression="$ctx:p-id" name="p-id-set"/>
            </log>
        </sequence>
    </target>
</iterate>

Also, an Iterate Mediator should be coupled with an Aggregate Mediator. So make sure you add appropriate aggregation logic as well.

Iterate mediator should not be considered as a for-loop in programming languages. When you Iterate over a payload, the Payload will be split and each segment will concurrently execute on its own thread. So having nested Iterate Mediators is not a good idea unless it's really necessary.

ycr
  • 12,828
  • 2
  • 25
  • 45
  • 1
    This works exactly the way I want it work. But again, I'm not sure if using $[0] would help me for every testcase as it has to be generic and we are not aware of the payload we would receive from the external system. Thanks for the solution :) – Ruby Sep 12 '22 at 13:00
  • 1
    @Ruby Glad, it helped. If you want to make it generic you can change the expression to `$[*].p_id` But again if you receive multiple records you may have to add some logic to handle it. – ycr Sep 12 '22 at 13:06