Search code examples
jsonyamlconditional-statementsgoogle-workflows

How to return specific item from Cloud Workflows instance?


I have the problem to get the data out of the JSON response instance. I am using Cloud Workflows to get the information about the current state of my VMs. I am using the the .get functions that returns this long JSON that is high structured, e.g. launchResult is returned as:

{
   "name":"some name",
   "status":"some status",
   "items":[
      {
         "key":"key1",
         "property1":"xxxx",
         "property2":"ccvdvdvd"
      },
      {
         "key":"key2",
         "property1":"xxxrerex",
         "property2":"ccvdveedvd"
      }
   ],
   "kind":"some kind"
}

I can return for example "some status", by ${launchResult.status}, even key1, as {launchResult.items[0].key}.

The question is: How can I do sth like launchResult.items["key" == "key1"].property1? I mean I want to return the property1 from the item based on the key.


Solution

  • To get the property from an item in an list of maps based on the value of another property of that map, I would suggest the following:

    • To iterate over the elements of the list until you get the one with the property you're looking for.

    This is a sample code I made to show how to use iterations along with conditionals in Cloud Workflows to achieve this:

    main:
      params: []
      steps:
      - define:
          assign:
            # Incremental variable set to zero
            - i: 0
            # Value to look up in list
            - cond: "key2"
            # A variable that contains a sample data as the JSON
            # showed in the question
            - test: 
                name: some name
                status: some status
                items:
                - key: "key1"
                  property1: xxxx
                  property2: ccvdvdvd
                - key: "key2"
                  property1: xxxrerex
                  property2: ccvdveedvd
                - key: "key3"
                  property1: xxex
                  property2: ccvdvffdvd
                kind: some kind
      - lookupInItems:
          switch:
            # Here we're looking for the element over the list test.items until the condition is met 
            # or the list ends
            - condition: ${i < len(test.items) and test.items[i].key!=cond}
            # If the condition is not met, keep iterating using iterate step
              next: iterate
          # If the element is found or the list ends, jumps to the read step
          next: read
      - iterate:
          assign: 
          # Increment the increment variable i
            - i: ${i+1}
          next: lookupInItems
      # If the iteration ends, check for the value
      - read:
          switch:
            # Check if the value was found
            # if this check is not made, an out of index error will occur when trying to show
            # the property of a value does not exists
            - condition: ${i < len(test.items)}
              next: found
          next: notfound
      # Print a message on the sys.log either the value was found or not
      - notfound:
          call: sys.log
          args:
            text: ${"Value " + cond + " not found in list"}
            severity: "WARNING"
          next: end
      - found:
          call: sys.log
          args:
            text: ${test.items[i].property1}
            severity: "INFO"
          next: end
    

    See also: