FME Version
Files
-
- 5 KB
- Download
Introduction
This tutorial creates a basic, scripted web application that demonstrates API job submission to FME Flow: Easy Translator Web App. This web application uses the easyTranslator.fmw workspace (an FME Flow sample workspace) to transform uploaded files into different data formats. HTML and JavaScript leverage Fetch for making REST API requests to the FME Flow Web Services.
The final result is a web form with two basic functions:
- Uploading a temporary file (via the Data Upload Service)
- Submitting a job (via the Data Download Service)
Use Case:
Custom web applications are a scripted alternative to no-code FME Flow Apps. FME Flow Web Services extend FME for use cases where FME Flow Apps do not fulfill workflow requirements such as scripted integrations, embedding FME Flow functionality into another application, or automating workflows outside the browser.
Prerequisites
- Basic understanding of REST API, HTML, and JavaScript
- A text editor
Publicly accessible web applications typically require a web server, a secure FME Flow and other networking configurations. Consult with your IT team to understand your organization's specific requirements.
Step-by-step Instructions
Part 1: HTML for Job Submission
This section assembles a basic web form in HTML. The form elements will correspond to the Published Parameters required for the easyTranslator workspace.
1. Basic HTML
In a text editor, create a basic HTML file. It should include all customary <doctype>, <html>, <head>, and <body> tags.
Inside the <body>, insert a <form> element. Assign it a descriptive id, like userParameterForm.
<!-- HTML Form -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Page Title -->
<title>Web Form with Fetch API Requests to FME Flow</title>
</head>
<body>
<!-- App Title -->
<h1>FME Easy Translator Web App</h1>
<!-- Form for FME Parameters -->
<form id="userParameterForm">
</form>
</body>
</html>
2. HTML Form with Workspace User Parameters
To run the easyTranslator workspace from the web form, workspace parameters need to be available to the end user. Details about the workspace parameters can be reviewed from the FME Form Parameter Manager. Parameters marked with an asterisk (*) are required, all others are optional.
The easyTranslator.fmw workspace is provided with every installation of FME Flow. Download it from the Samples repository to open it in FME Form.
The FME Form Parameter Manager for the easyTranslator.fmw workspace.
Parameters can be defined in the HTML. Different HTML elements support different kinds of parameter types, for example:
• File parameters can be handled by <input type="file">
• Text parameters can be handled by <input type="text">
• Choice parameters can be handled by <select>
Inside the HTML <form> element, create elements for the workspace parameters. In this simplified example, we will only provide some of the easyTranslator parameters to the user. The rest of the parameters will be submitted with default values later in the tutorial.
<form id="userParameterForm">
<!-- File Upload for File Parameters -->
<label for="fileUpload">Source file:</label>
<input type="file" id="fileUpload" name="fileUpload"><br><br>
<!-- Drop-down for Choice Parameters -->
<label for="sourceFormatChoice">Source Format:</label>
<select name="sourceFormatChoice" id="sourceFormatChoice">
<!-- (Dropdown options for source format) -->
</select><br><br>
<!-- Drop-down for Choice Parameters -->
<label for="destFormatChoice">Destination Format:</label>
<select name="destFormatChoice" id="destFormatChoice">
<!-- (Dropdown options for destination format) -->
</select><br><br>
<!-- Textbox for Text Parameters -->
<label for="destFileName">Destination File Name:</label>
<input type="text" id="destFileName" name="GENERIC_OUT_BASE_NAME_GENERIC" placeholder="Enter file name here"><br><br>
</form>
3. User Parameter Values
Some parameter types have defined values. Details about parameter values can be reviewed in the configuration details for each user parameter. For example, “choice” parameters have values that the user can select from.
A list of potential values for the SourceFormat parameter can be found in the Choice Configuration.
Our web app should supply the same parameter values in the HTML. For each HTML element, fill in values for user parameter drop-down options or placeholder text.
- The parameter “Value” can be a drop-down text option: <option value="ACAD">
- The parameter “Display” can be the drop-down label text: <option value="ACAD">Autodesk AutoCAD DWG/DXF</option>
<!-- Form for FME Parameters -->
<form id="userParameterForm">
<!-- File Upload for File Parameters -->
<label for="fileUpload">Source file:</label>
<input type="file" id="fileUpload" name="fileUpload"><br><br>
<!-- Drop-down for Choice Parameters -->
<label for="sourceFormatChoice">Source Format:</label>
<select name="sourceFormatChoice" id="sourceFormatChoice">
<!-- (Dropdown options for source format) -->
<option value="GUESS_FROM_EXTENSION">Allow FME to guess!</option>
<option value="ACAD">Autodesk AutoCAD DWG/DXF</option>
<option value="CSV">Comma Separated Value (CSV)</option>
<option value="GEOJSON">GeoJSON (Geographic JavaScript Object Notation)</option>
<option value="GPX">GPS eXchange Format (GPX)</option>
<option value="IGDS">Bentley MicroStation Design (V7)</option>
<option value="MIF">MapInfo MIF/MID</option>
<option value="MITAB">MapInfo TAB (MITAB)</option>
<option value="OGCKML">Google Earth KML</option>
<option value="SDF3">Autodesk MapGuide Enterprise SDF</option>
<option value="SHAPEFILE">Esri Shape</option>
<option value="SQLITE3FDO">SQLite Spatial (FDO)</option>
<option value="GML">GML (Geography Markup Language)</option>
</select><br><br>
<!-- Drop-down for Choice Parameters -->
<label for="destFormatChoice">Destination Format:</label>
<select name="destFormatChoice" id="destFormatChoice">
<!-- (Dropdown options for destination format) -->
<option></option>
<option value="ACAD">Autodesk AutoCAD DWG/DXF</option>
<option value="CSV">Comma Separated Value (CSV)</option>
<option value="GEOJSON">GeoJSON (Geographic JavaScript Object Notation)</option>
<option value="GPX">GPS eXchange Format (GPX)</option>
<option value="IGDS">Bentley MicroStation Design (V7)</option>
<option value="MIF">MapInfo MIF/MID</option>
<option value="MITAB">MapInfo TAB (MITAB)</option>
<option value="OGCKML">Google Earth KML</option>
<option value="SDF3">Autodesk MapGuide Enterprise SDF</option>
<option value="SHAPEFILE">Esri Shape</option>
<option value="SQLITE3FDO">SQLite Spatial (FDO)</option>
<option value="GML">GML (Geography Markup Language)</option>
</select><br><br>
<!-- Textbox for Text Parameters -->
<label for="destFileName">Destination File Name:</label>
<input type="text" id="destFileName" name="GENERIC_OUT_BASE_NAME_GENERIC" placeholder="Enter file name here"><br><br>
</form>
4. Submit Button
Add a button to the web form that will allow the end-user to submit their parameters. Place the snippet after the parameters, before </form>.
<!-- Submit Button for FME Flow File Upload and Job Submission -->
<button type="button" id="submitButton">Submit</button>
5. Message Display
Add a container to the end of the form that will display a download link to the end. Place the final snippet between the </button> and </form>.
<!-- Placeholder for Message Display -->
<div id="message"></div>
The final HTML web form will have a title, parameters, parameter values, and a submission button.
A basic HTML web form built for the easyTranslator.fmw workspace.
Continue to Part 2 to allow this web form to make API requests to FME Flow.
Part 2: JavaScript for Job Submission
JavaScript enables an HTML web form to be responsive and interactive. This JavaScript example uses Fetch to make API requests to FME Flow Web Services that upload a file and submit a job.
In summary, this workflow can be broken down into 3 JavaScript functions:
- handleSubmit: makes the web form button responsive
- uploadFile: uploads the selected file to FME Flow
- submitForm: submits a job to FME Flow
When testing JavaScript, open the browser's Developer Tools' Console window to review the data logged by the console.log methods in the script. Open the Network window to review the API requests.
1. Basic Script
The JavaScript section can be added to a separate file (*.js) or embedded in the HTML. This tutorial example will do the latter by placing the <script> object inside the <head> tag, after <title>. The script snippet contains placeholders for our 3 functions.
<script>
function handleSubmit() {
// responds to the user pressing the HTML button.
}
function uploadFile() {
// responds to a successful handleSubmit function by making a POST request to FME Flow.
}
function submitForm() {
// responds to successful uploadFile function by submitting a Job to FME Flow.
}
</script>
2. Orchestrating Requests to FME Flow
The handleSubmit function responds to the user pressing the web form button by orchestrating the API requests to FME Flow.
The handleSubmit function must be connected to the HTML web form. Inside the HTML, update the button to include an onclick property. Set the value to the handleSubmit() function.
<!-- Submit Button for FME Flow File Upload and Job Submission -->
<button type="button" id="submitButton" onclick="handleSubmit()">Submit</button>
Inside the JavaScript, add the handleSubmit function snippet.
function handleSubmit() {
// Responds to the user pressing the Submit button.
uploadFile().then(submitJob).catch(error => console.error("Error during submission:", error));
}
This function orchestrates the functions in the order (uploadFile followed by submitForm) that FME Flow expects to receive their requests.
3. FME Flow Definitions
Before we can make API requests to FME Flow, we need to define connection parameters.
Directly after <script>, define your FME Flow parameters. These object values can be updated inside each function as needed.
// Define FME Flow parameters
const fmeflow = {
url: "https://<my-fme-flow-URL>.com",
repository: "Samples",
workspace: "easyTranslator.fmw",
service: null,
token: "fmetoken token=" + "<API-token>"
}
- The workspace and repository names are case-sensitive
- Make sure the API token has access to the required workspace repositories, folders, and services. In this example, the easyTranslator.fmw workflow requires the Samples repository, Data Download (Services), and Data Upload (Services).
4. File Upload
From the web form, a user can select a local file for translation. This file needs to be uploaded to FME Flow before it can be used in the job. The uploadFile function makes an API request to the FME Flow Data Upload Service.
Declare a global variable for the uploaded file. Place the snippet directly above the uploadFile() function.
// Create placeholder for the input file's FME Flow file path
let uploadedFileResponse = null;
Inside the uploadFile function, add the snippet.
function uploadFile() {
// Responds to a successful handleSubmit function by making a POST request to FME Flow.
const fileInput = document.getElementById('fileUpload');
if (fileInput.files.length === 0) {
alert('Please select a file to upload.');
return Promise.reject('No file selected'); // Immediately reject the promise
}
// Create a variable for the submitted file to be used in the upload Request body
const formData = new FormData();
formData.append('file', fileInput.files[0]);
// Define query parameters
const queryParams = {
opt_fullpath: true,
opt_pathlevel: 1,
opt_namespace: "Easy Translator Web App",
};
// Convert query parameters object into a query string
const queryString = new URLSearchParams(queryParams).toString();
// Define the FME Flow service
fmeflow.service = "fmedataupload";
// Create FME Flow Data Upload Request URL
const requestURL = `${fmeflow.url}/${fmeflow.service}/${fmeflow.repository}/${fmeflow.workspace}`;
// Define headers as an object
const headers = new Headers({
"Authorization": fmeflow.token
});
// Return the fetch Promise so it can be used for chaining
return fetch(`${requestURL}?${queryString}`, {
method: 'POST',
body: formData,
headers: headers,
})
// Parse the response and store the FME Flow file path in the uploadedFileResponse variable
.then(response => response.json())
.then(data => {
console.log(data);
uploadedFileResponse = data.serviceResponse.files.file[0].path;
console.log(uploadedFileResponse);
document.getElementById('message').textContent = 'File uploaded';
})
.catch(error => {
console.error(error);
document.getElementById('message').textContent = 'Data submission failed';
return Promise.reject(error); // Ensure the chain is properly failed
};
}
- The queryParams object values can be configured. Review Request Parameters in the documentation.
- The requestURL is the request URL pattern that is defined in the documentation.
- The formData is created from the file selected in the HTML web form (input type="file")
5. Job Submission
After the user's file is uploaded to FME Flow, the job can be submitted. The submit function makes a GET request to the FME Flow Job Submitter Service.
In the JavaScript, add the submitJob function snippet.
function submitJob() {
// responds to successful uploadFile function by submitting a Job to FME Flow.
const messageElement = document.getElementById('message');
messageElement.textContent = 'Submitting the job...';
const queryParams = {
// Create Query String Parameters from Form Responses
SourceDataset_GENERIC: uploadedFileResponse,
SourceFormat: document.getElementById('sourceFormatChoice').value,
GENERIC_OUT_BASE_NAME_GENERIC: document.getElementById('destFileName').value,
DestinationFormat: document.getElementById('destFormatChoice').value,
// Default parameters
opt_showresult: "true",
opt_servicemode: "sync",
opt_responseformat: "json"
};
// Convert query parameters object into a query string
const queryString = new URLSearchParams(queryParams).toString();
// Define the FME Flow service
fmeflow.service = "fmedatadownload";
// Create FME Flow Data Upload Request URL
const requestURL =`${fmeflow.url}/${fmeflow.service}/${fmeflow.repository}/${fmeflow.workspace}`;
// Define headers as an object
const headers = new Headers({
"Authorization": fmeflow.token
});
// Parse the response and return the FME Data Download results in the Web Form
return fetch(`${requestURL}?${queryString}`, {
method: 'GET',
headers: headers
})
.then(response => response.json())
.then(data => {
console.log(data);
const downloadLink = data.serviceResponse.url;
console.log(downloadLink);
messageElement.textContent = '';
// Create an anchor element and set its properties
const linkElement = document.createElement('a');
linkElement.href = downloadLink;
linkElement.textContent = 'Download Results';
// Clear the message container and append the anchor element
messageElement.appendChild(linkElement);
})
.catch(error => {
console.error(error);
document.getElementById('message').textContent = 'Error in processing.';
});
- The fmeflow.service is updated to ‘fmedatadownload’
- The fetch request method is GET (instead of POST)
- The download link for results is sent to the message container
6. Web Form Responsiveness
Lastly, the web application will perform a simple validation of the data before it is submitted to FME Flow. The “Submit” button will only become enabled when the user completes the required parameters. This will prevent users from submitting incomplete jobs to FME Flow and receiving errors. To do this, we will use another JavaScript event listener to make the HTML form responsive.
The button should be disabled by default. In the HTML, add a “disabled” qualifier:
<!-- Submit Button for FME Flow File Upload and Job Submission -->
<button type="button" id="submitButton" onclick="handleSubmit()" disabled>Submit</button>
We know that the easyTranslator workspace only requires three parameters: Source File, Source Format, and Destination Format. In the JavaScript, add an event listener to the top of the script (before the handleSubmit function).
// Enable Submit button after file is selected
document.addEventListener('DOMContentLoaded', function () {
const fileInput = document.getElementById('fileUpload');
const destFormatChoice = document.querySelector('select[name="destFormatChoice"]');
const submitButton = document.getElementById('submitButton');
function checkFormConditions() {
const isFileSelected = fileInput.files.length > 0;
const isDestFormatSelected = destFormatChoice.value !== "";
submitButton.disabled = !(isFileSelected && isDestFormatSelected);
}
fileInput.addEventListener('change', checkFormConditions);
destFormatChoice.addEventListener('change', checkFormConditions);
});
This step completes the JavaScript and HTML scripting to create a basic web form that interacts with FME Flow. Download and review the exercise files to build it yourself.
The files provided in this exercise need to be updated with values specific to your FME Flow installation. These scripts are provided only as examples and are not suitable for a production environment without review.
7. Customization (Optional)
Integrating FME Flow Web Services into web applications opens up the doors for complete customization. The final Easy Translator web application uses CSS for custom colors, borders, fonts, and logos. The exercise files include the CSS stylesheet embedded in the HTML file.
Comments
0 comments
Please sign in to leave a comment.