Skip to main content

Today I'm breaking my rule of never manually (or automatically) editing a workspace file, in order to dynamically update a choice-type user parameter.

Question of the Week

This question was asked by @philippeb who needs to send a list of names to a survey choice field. 

Q) Our employees fill a weekly survey about their health and their kids going to summer camp activities.

The survey  fields] change in time, depending on the kids that subscribed. The subscribed kids are exported into an Excel file every week. 

 

I thought to read the file with FME and push the kids into the survey every week. That way the list of kids in the survey could change without our help. And the kid (or his parent) could select his name to fill the survey.

The issue is that we don't know any survey platform able to change automatically from a script. Do you know if any kind of platform could change when FME pushes new values into it?

A) I know of a platform that could be used to provide a weekly survey: FME Server! After all, that's what I use for the weekly FME Quiz. A simple Server app takes the place of a survey tool, and you could set up the underlying workspace to carry out all sorts of tasks (like calculating statistics or emailing participants).

 

The question is, can we set up a Choice parameter in FME that updates the list of choices dynamically?

What I Tried First Of All

Is there a way to do this "officially" in FME? Well, the Choice type parameter has an import option, but it's static. You can import a list when you create the parameter, but you can't force it to automatically regenerate the list from a source when you run the workspace.

0684Q00000ArCXNQA3.png

A Scripted parameter also sounds like it might work, but it doesn't present options at all to the users. So it could take a name from the Choice parameter and check the name's validity, but it can't restrict the choice in the first place.

So is there a way to do this "semi-officially".

What Is Pretty Cool, But Doesn't Quite Fit

These are the types of hack that I love, where you use functionality intended for one purpose, in a completely different way.

Let's see... are any user parameter types dynamic? 

Actually, yes. The Feature Types to Read parameter is dynamic. Let's say I set up a processing workspace that reads the list of children's names from Phillipe's Excel file. I could then create a database table for each child.

Then the actual workspace, instead of using a Choice parameter, uses the Feature Types to Read parameter:

0684Q00000ArCUDQA3.png

The end-user thinks they are picking from a list of names, when in fact we're dynamically giving them a list of database tables! The difference doesn't matter because we only want to know what their selection is. We don't even need to read from the database tables, just use the value of the parameter.

The problem is... this isn't a Single Choice parameter, but a Multiple Choice parameter. I could select multiple names from the list, when really we want only one.

So it's a really nice, hacky idea, but it's not going to work here.

But there is a very "unofficial" method that will work...

What I'm Reluctant To Do, But Works!

I'm generally against editing a workspace file manually; like opening your fmw file in a text editor and making changes. It's not as simple as you'd think and you could cause some major problems.

However... the definition for user parameters is pretty straightforward, so let's risk it in this case!

So my method is this. I have a base workspace that runs my survey. It has a whole bunch of questions, like:

  • Select Child Name
  • Enter Child Age
  • Select Preferred Activity Date

I have that set up in an FME Server app, like so:

0684Q00000ArCXSQA3.png

The important parameter is the one Select Child Name. Opening up the fmw file in a text editor, I can see it is defined in two places:

#!   GUI_LINE="GUI CHOICE_OR_ATTR kidName DEFAULT Name of Child:"
GUI CHOICE kidName DEFAULT Name of Child:

I set it up with a single choice of DEFAULT, so what I have to do is substitute that line with one that replaces DEFAULT with the list of proper names, read from the Excel dataset.

I obviously do that with a second workspace, which looks like this:

0684Q00000ArCVcQAN.png

I read from the Excel file (actually I'm using a plain text file) and aggregate the names together. The Aggregator will kindly concatenate all the names together, separating them with a % character, which is what the parameter definition expects.

The AttributeCreator creates my replacements for the above lines, i.e. this:

GUI CHOICE kidName @Value(text_line_data) Name of Child:
#!   GUI_LINE="GUI CHOICE_OR_ATTR kidName @Value(text_line_data) Name of Child:"

The AttributeFileReader reads the contents of the base workspace, the StringReplacer updates the two strings, and then the AttributeFileWriter writes the file back again.

I write to a new file name so that I always have the original as a template.

Finally, I publish the base workspace back to FME Server, and the app automatically updates with the new names from the Excel file.

Voila!

Summary

So the original question asked only about using FME to write values to an existing survey platform; but I believe that with FME Server apps, you can do the same sort of thing, but with the added value of FME data transformation and automation.

I'm not wild about doing edits to a workspace outside of Workbench, but it's fairly risk-free for this scenario.

Overall - even without the dynamic parameters - I think this is a great example of the sort of non-spatial project that you can use FME for.

Other Notable Questions

Here are a few other interesting questions from this week:

  • Dynamically created a WFS XML query
    • More dynamics, this time dynamically creating an XML query for @redgeographics with the XMLTemplater. I really love the XQuery content from @ebygomm that solves the requirement. Great work!
  • Cannot select Hub formats and Custom Formats in 2020
    • There was a problem in early 2020.0 versions where you couldn't use or install a custom format from the FME Hub. This is now fixed in the latest .0 updates.
  • Clip Vector Data from Multiple Shapes
    • @ienesaglam60 asked how to clip data across tile boundaries, but keep the clipped features whole. @markatsafe demonstrates how to do that, by assessing which part of the clipped feature is the largest, and rebuilding the feature in that tile. Now there's a need to keep the same feature in both tiles, which I suspect will be quite straightforward.
  • BulkAttributeRenamer not renaming
    • This transformer is actually one of my favourites, mostly because it renames so many attributes, in so many ways, and exposes all of the renamed attributes in the canvas. I think that's great. Why wasn't it working for @jlbaker2779? Because the prefix being added was determined by a user parameter. This goes back to a very early question-of-the-week, which dealt with why you can't see attributes created dynamically when you are still authoring the workspace. It also talked about how you also need to set up a dynamic writer, which will also be needed in this question.
  • Read Only Changed Rows From a Database
    • This is older than a week, but I find it a very interesting question from @benros. I think I recently discussed in a question about Change Detection how to do change detection to find these rows; and @benros has an adequate solution anyway. But recently I came across the idea of using system logs to do this sort of task. For example, Write-Ahead Logging is meant to keep a record of what is about to be written, just in case there is a system failure. But could those logs be used to identify changed records? Wikipedia tells me that "some 1databases] provide programmatic interfaces to their transaction logs" so you might be able to use those, or we might even be able to create a new reader to get that information! Anyone with more database knowledge than I know how these work?

For me the second method with the multiple choice parameter was exactly what I needed. It feels more comfortable than changing the Workspace automatically.

Thanks for sharing, @mark2atsafe!


Hi @mark2atsafe​ 

 

The second problem with the multiple choice parameters seems to be the fact that FME Server does not create a dropdown menu for the Feature Types. Tested this with a PostGIS database and a SQLite file. Can you confirm?


Reminds me og when I started using FME regular 7 years back. Using FME inside out. Its easy to get trapped with parameters, I would rethink the problem to see if it can be completly avoided. Do we need a published parameter with a choice option for a name type? Why not text, and do the logical mapping to the database later.


In fmeserver this should be a good solution, but not working with fmecloud as far as I can see. It is not possible to set "AttributeFileWriter writes the file back again". Please correct me if I'm wrong.


I am stuck at the step with choosing only one option instead of several options. 

Does anyone can help me to create from this line that only option can be chosen?

GUI_LINE="GUI FEATURE_TYPES_OR_ATTR_ENCODED FEATURETYPES

I created an user parameter of the features to read and it's called featuretypes. I am just a bit surprised that the notation is in the example is quite different 

GUI CHOICE kidName DEFAULT Name of Child:

 

 


I am stuck at the step with choosing only one option instead of several options. 

Does anyone can help me to create from this line that only option can be chosen?

GUI_LINE="GUI FEATURE_TYPES_OR_ATTR_ENCODED FEATURETYPES

I created an user parameter of the features to read and it's called featuretypes. I am just a bit surprised that the notation is in the example is quite different 

GUI CHOICE kidName DEFAULT Name of Child:

 

 

Hey @joy​ not entirely sure what the error your receiving is, or what your expected output would be. I know a lot of things have changed with FME in the last 3 years though. There's even more advanced parameter functionality coming in 2023.0, try the beta!

 

What version of FME are you using?

Perhaps you could post this as a separate question on the community and link back to this post with the additional information? This is so that there could be more visibility from the wider community and potentially get more answers :) 


@mark2atsafe​ 

The chosen method is ok even though it should be much easier to update a list in a user parameter. The thing I wonder is if this is possible to do without opening a FME workspace, thus run that workflow of yours in FME Server; open the new updated list, aggregated and replace the old list with the new and then post the FME workspace to FME server. I tried that approach but it doesn't seem to update the list in the user parameter.


@mark2atsafe​ 

The chosen method is ok even though it should be much easier to update a list in a user parameter. The thing I wonder is if this is possible to do without opening a FME workspace, thus run that workflow of yours in FME Server; open the new updated list, aggregated and replace the old list with the new and then post the FME workspace to FME server. I tried that approach but it doesn't seem to update the list in the user parameter.

Fortunately, this functionality is already being developed for FME. A Choice parameter in Flow will be able to read a list of choices from... possibly another workspace output? We're not really sure what form this will take. There are many challenges, as you are finding out. But it's happening and I'm hopeful it will be in FME 2024 (but I can't guarantee that, of course).


Reply