How can I assign a default channel to another channel if it’s empty, while retaining its original content when it’s not empty, considering the default value is also a channel?

Hi all,
I’m working on a larger workflow and have encountered a challenge. Here’s the scenario:
I have a channel v1, which may sometimes be empty. In that case, I want to assign another channel sample (holding [SNP-2024-FT]) to v1. However, if v1 is not empty, it should retain its original value.
Here’s the code snippet I tried:

groovy


params.sampleId = "SNP-2024-FT"

workflow {
    input_ch = Channel.of(
        tuple(params.sampleId)
    )
    sample = input_ch.map { it -> [it[0]] }
    sample.view()

    v1 = Channel.empty().ifEmpty(true).map { value ->
        if (value == true) {
            sample
        } else {
            value
        }
    }
    v1.view()
}

The issue is that this gives the error: DataflowBroadcast around DataflowStream[?]. It seems related to the fact that sample is itself a channel, not a static value, and the ifEmpty(true) only works with direct static values.
Additionally, consider that Channel.empty() is an empty output channel from a process in this context, so the behavior of assigning it can be tricky. When I set a direct value like ifEmpty("some value"), it works, but since sample is an output channel, it’s always a channel rather than a direct value.
Does anyone know how to work around this or handle such cases? Any advice or alternative approaches would be greatly appreciated!
Thanks in advance!

Hi @Kanna_Dhasan,

I believe the snippet below will be helpful for you.

Channel
  .of(params.sample_id)
  .flatMap()                                                                                                                                                            
  .ifEmpty('Hello')
  .view()

Output

Here’s one way to solve the problem of if one channel is empty, use another one.

params.fill = false

workflow {
    ch_something = params.fill ? Channel.of(1..3) : Channel.empty()
    ch_backfill = Channel.of(4..6).toList()
    ch_something.collect().concat(ch_backfill).first().flatMap().view()
}

This uses the property that collect only emits a list if there’s something in the channel. Use concat to make sure the channel contents stay in order. and then use first() to take the first list from the concatenated channels. If ch_something is empty, there will be nothing, and the list from ch_backfill is taken.

1 Like

Thank you so much for your response! Just to clarify, ifEmpty only accepts direct static values and not channels. However, in my case, if the channel is empty, I want to assign another channel. Here, sample is a value channel holding a single value

1 Like

@mahesh.binzerpanchal Thank you so much for this workaround! It works exactly as I needed and solves my problem perfectly. I really appreciate your help! :slightly_smiling_face:

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.