Help with nested loops and the new WithName() formula

@Breno_Nunes hey what do you think about creating a button column in your table, allowing you to break up that formula a bit and then have the canvas button (or you could use an automation) push all the buttons in the table. I would start there and see how that changes your approach.

My formula was exactly like that. I had a button column. The thing is it works when you have fewer then a thousand rows. It get really slow after that. Sometimes it doesn’t even finish processing.
With the new WithName() , I was able to do nested loops and it runs really fast but it can get a little complicated.

I cleaned up your formula to make it easier to read:

 SourceTable.FormulaMap(
  WithName(CurrentValue, CurrentRow,
    SwitchIf(CurrentRow.[N° of Pictures] != 0, 
      Sequence(1, CurrentRow.[N° of Pictures]).FormulaMap(
        WithName(CurrentValue, CurrentName,
          Pictures.AddRow(
            Pictures.Name, CurrentRow.[List of Names].Nth(CurrentName),
            Pictures.Code, Left(CurrentRow.Description, 7)
          )
        )
      ) , _Noop()
    ) 
  )
)

Wait, so what’s wrong with the formula as it is? It seems to work
I’ve now cleaned it up a bit, but it still does the same thing:

SourceTable.FormulaMap(
  WithName(CurrentValue, CurrentSource,
    CurrentSource.[List of Names].FormulaMap(
      WithName(CurrentValue, ImageName,
        Pictures.AddRow(
          Pictures.Name, ImageName,
          Pictures.Code, CurrentSource.Description.Split(" ").First()
        )
      )
    ) 
  )
)

Edit: Ah, you want it to change the content of the Done? column. I have also had trouble getting that to work. You would think this formula would work, but it does not:

SourceTable.FormulaMap(
  WithName(CurrentValue, CurrentSource,
    RunActions(
      CurrentSource.ModifyRows([Done?], True()),
      CurrentSource.[List of Names].FormulaMap(
        WithName(CurrentValue, ImageName,
          Pictures.AddRow(
            Pictures.Name, ImageName,
            Pictures.Code, CurrentSource.Description.Split(" ").First()
          )
        )
      )
    )
  )
)

Even switching it out with an in-row button that marks done and using RunActions(CurrentSource.[Mark Done]) doesn’t work.

I just consistently get this error:
_DEREF expects parameter input to be either a row from an unknown table or a list of rows from an unknown table, but found value (’’), which is an unknown value

Even tried to remove the second WithName, but the problem persists.

SourceTable.FormulaMap(
  WithName(CurrentValue, CurrentSource,
    RunActions(
      CurrentSource.[Mark Done],
      CurrentSource.[List of Names].FormulaMap(
        Pictures.AddRow(
          Pictures.Name, CurrentValue,
          Pictures.Code, CurrentSource.Description.Split(" ").First()
        )
      )
    )
  )
)

Hi, @cnr. Thank you for your help.
I get the same error message. I must be a bug.
I’ve contacted Coda’s support to see if they can figure this out.
Maybe there’s something to do with RunActions() inside WithName() that is not working well.
Thank you again.

Yeah, I’m running into that problem in another doc as well. It seems that WithName and RunActions don’t play nice quite yet.

Another strange behavior.
swtichif() unlike If() doesn’t ask for a third argument.
You can always write formulas like switchif( thisRow= “n”, true).
In this case, if you remove _noop() it breaks the formula.

1 Like

I think that’s intentional. If expects to bifurcate, switchif expects between 1 and n conditions.

I understand but it shouldn’t break my formula.
If I’m using switchif(), there would be no need to include _noop() as the third argument.
It should just work.

ohhh I see what you’re saying. Yeah I would agree. It should be implicit

Hi, @cnr.
I’ve contacted Coda support and @alden gave me this answer:

Hi Breno, thanks for reaching out. I don’t think this is a bug although the error message is unclear. The RunActions() needs to be the outermost call.

You can’t code WithName(… RunActions(…)…) . I guess it was meant to be this way for some reason.

Breno

1 Like

Huh weird. It would be interesting to know why, but at least we have an answer

So there was a bit lost in translation here. Currently this is the case because of an oversight when working on WithName. The TLDR is that this is a bug, I have a fix and it should deploy on Monday.

A point of confusion here is that the Coda Formula Engine and Action Engine are two independent systems. The formula language has formulas in it which return actions but does not run them. The action engine executes actions, which may or may not have been generated by the formula language. In this manner the formula language never has side effects and can be re-run an unlimited times without harm.

RunActions is one of our more advanced meta actions that basically says defer the evaluation of my expression parameters. Then it bundles up those formula expressions into a payload. The bug here was that we were not passing all of the context needed to support WithName in this payload for the action engine to execute the deferred expression inside of RunActions.

Sorry about missing this. It should be fixed shortly.

5 Likes

Hi, @Jason_Tamulonis.
I think WithName() is still buggy.
I made a very simple mock doc to show you where the problem is.
I’m getting this error message “Invalid source for projection.”
There are 3 button. They have very similar formula but one of them doesn’t work.
Could you please take a look at it?
Thank you

Hi @Breno_Nunes ,
I think that the issue resides in a FormulaMap() that is missing (I provided an implementation as additional column).

Tell me if it’s not clear.

Cheers!

1 Like

Thank you, @Federico_Stefanato .
Can you explain why FormulaMap() is necessary in this case?
Why couldn’t I just do Orders.Filter(Unarchive).WithName(...) instead? Why it worked in one case and it didn’t in other?
I understand that you need FormulaMap() if more than one unarchive box was checked. Otherwise I didn’t think it was necessary.

Hi @Breno_Nunes ,
basically you are asking the button - in plain english:

Hey, would you please create a new row in the Item table for every entry that is selected in the Orders table

The key here is for every and the only way to instruct the processor to do that is through FormulaMap().

The WithName() function only allows to, well, give a name to an expression.

I have the feeling you might have interpreted the RunActions() as an implicit FormulaMap()
For every row of my dataset do…”.
As a matter of fact, RunActions() allows just to group sequentially different actions; for this reason, here is redundant (but working)

So let’s dissect the formula:

Orders.Filter(Unarchive) // let's take the selected orders
    .FormulaMap( // for each Order record we have
    CurrentValue.WithName(ChosenOrder, // give it the name ChosenOrder and...
    Item.AddRow( // add a new row on Item table
        Item.[Order Number],ChosenOrder.[Order Number] // with the values taken from the current ChosenOrder
)))

In this case you should need to have a record reference (such as First() or Nth() or Last()) in order to execute an action on that record.

Please, tell me otherwise.
Cheers!

7 Likes

Dear @Federico_Stefanato,

Excellent explanation, you make coding in this way understandable, with an easy entrance level :trophy::trophy::trophy:

Much appreciated :pray:

3 Likes

Thank you very much @Federico_Stefanato for you explanation.
Actually RunAction() is not redundant for my use case. As this was only a mock doc, I didn’t mind adding a “2° action”
Still I did work with Orders.Filter(Unarchive).first() or using .FormulaMap(). as you said.
It helped me a lot. Thank you