1 Introduction
To help you to find out how you can write code to alter your model, the SDK ships with a nice reverse engineering tool. Given a fully loaded model unit, you can generate the JavaScript code that would create that very same unit using code. This way, you can build a template model in Studio Pro, then generate the code you would need to write to achieve the same.
2 For the Impatient
To generate the code for a fully-loaded unit you can use the following code:
import { JavaScriptSerializer } from "mendixmodelsdk";
console.log(JavaScriptSerializer.serializeToJs(someFullyLoadedModelUnit));
3 Example
Let’s say you want to generate a set of entities in a domain model that looks like this:
First you need to create the two entities in the domain model and commit that to Team Server. Next, you need to write a script like this:
import { ModelSdkClient, IModel, IModelUnit, domainmodels, JavaScriptSerializer } from "mendixmodelsdk";
import { MendixSdkClient, Project, OnlineWorkingCopy, loadAsPromise } from "mendixplatformsdk";
const username = "{YOUR_USERNAME}";
const apikey = "{YOUR_API_KEY}";
const client = new MendixSdkClient(username, apikey);
// Please change your project Id and name to something you prefer.
let projectName = "{YOUR_PROJECT_NAME}";
let projectId = "{YOUR_PROJECT_ID}";
let moduleName = "MyFirstModule";
let project = new Project(client, projectId, projectName);
async function serializeToJs() {
const workingCopy = await project.createWorkingCopy();
const domainModelInterface = workingCopy.model().allDomainModels().filter(dm => dm.containerAsModule.name === moduleName)[0];
try {
const domainModel = await loadAsPromise(domainModelInterface);
console.log(JavaScriptSerializer.serializeToJs(domainModel)); //print out the generated JavaScript
console.log("success!")
} catch (error) {
console.log(`error: ${error}`);
}
}
serializeToJs();
When you execute the script, you will get the following output of your console. You can also pipe the output to a file if the model is more complex:
(function (domainModel1, model) {
/*
* JavaScript code generated by mendixmodelsdk.sdk.extras.JavaScriptSerializer
* from unit with id '84776610-13b2-48cb-a265-d5e984d63129' of type DomainModels$DomainModel
* in working copy 'TS-585506fb-1348-4573-adb8-c778c8f2e9ad/null@null'
* on 23-11-2015.
*/
var noGeneralization1 = domainmodels.NoGeneralization.create(model);
noGeneralization1.persistable = true;
var stringAttributeType1 = domainmodels.StringAttributeType.create(model);
stringAttributeType1.length = 200;
var storedValue1 = domainmodels.StoredValue.create(model);
var address = domainmodels.Attribute.create(model);
address.name = "Address";
address.type = stringAttributeType1; // Note: for this property a default value is defined.
address.value = storedValue1; // Note: for this property a default value is defined.
var stringAttributeType2 = domainmodels.StringAttributeType.create(model);
stringAttributeType2.length = 200;
var storedValue2 = domainmodels.StoredValue.create(model);
var phone = domainmodels.Attribute.create(model);
phone.name = "Phone";
phone.type = stringAttributeType2; // Note: for this property a default value is defined.
phone.value = storedValue2; // Note: for this property a default value is defined.
var person = domainmodels.Entity.create(model);
person.name = "Person";
person.location = {"x":210,"y":230};
person.generalization = noGeneralization1; // Note: for this property a default value is defined.
person.attributes.push(address);
person.attributes.push(phone);
var noGeneralization2 = domainmodels.NoGeneralization.create(model);
noGeneralization2.persistable = true;
var stringAttributeType3 = domainmodels.StringAttributeType.create(model);
stringAttributeType3.length = 200;
var storedValue3 = domainmodels.StoredValue.create(model);
var roleName = domainmodels.Attribute.create(model);
roleName.name = "RoleName";
roleName.type = stringAttributeType3; // Note: for this property a default value is defined.
roleName.value = storedValue3; // Note: for this property a default value is defined.
var role = domainmodels.Entity.create(model);
role.name = "Role";
role.location = {"x":590,"y":230};
role.generalization = noGeneralization2; // Note: for this property a default value is defined.
role.attributes.push(roleName);
var associationDeleteBehavior1 = domainmodels.AssociationDeleteBehavior.create(model);
var role_Member = domainmodels.Association.create(model);
role_Member.name = "Role_Member";
role_Member.deleteBehavior = associationDeleteBehavior1; // Note: for this property a default value is defined.
role_Member.parentConnection = {"x":0,"y":54};
role_Member.childConnection = {"x":100,"y":51};
domainModel1.entities.push(person);
domainModel1.entities.push(role);
domainModel1.associations.push(role_Member);
role_Member.parent = role;
role_Member.child = person;
})
If you want to re-create the entities of an existing domain model, you will need to alter the script a little bit. Replace the first line with:
function generate(domainModel1, model) {
The original code expects a unit as the first argument. The unit is supposed to be the container for the domain model. However, you don’t want to create a new domain model, you are going to re-use an existing domain model instead. Therefore, you need to remove this line:
const domainModel1 = domainmodels.DomainModel.createIn(unit);
Remove the last bracket on the last line so your JavaScript code will look like this:
(function (domainModel1, model) {
/*
* JavaScript code generated by mendixmodelsdk.sdk.extras.JavaScriptSerializer
* from unit with id '84776610-13b2-48cb-a265-d5e984d63129' of type DomainModels$DomainModel
* in working copy 'TS-585506fb-1348-4573-adb8-c778c8f2e9ad/null@null'
* on 23-11-2015.
*/
var noGeneralization1 = domainmodels.NoGeneralization.create(model);
noGeneralization1.persistable = true;
.
.
.
.
.
.
role_Member.parentConnection = { "x": 0, "y": 54 };
role_Member.childConnection = { "x": 100, "y": 51 };
domainModel1.entities.push(person);
domainModel1.entities.push(role);
domainModel1.associations.push(role_Member);
role_Member.parent = role;
role_Member.child = person;
}
For the next step, you will create a script that make use of the function. The script is written in TypeScript, so it will be able to run a JavaScript code just fine. This script will create a blank project and modify the domain model in the ‘MyFirstModule’ module.
import { MendixSdkClient, Project, OnlineWorkingCopy, loadAsPromise } from 'mendixplatformsdk';
import { IModel, domainmodels, utils, projects } from 'mendixmodelsdk';
const username = `{YOUR_USERNAME}`;
const apikey = `{YOUR_API_KEY}`;
const client = new MendixSdkClient(username, apikey);
async function main() {
const app = await client.platform().createNewApp(`GeneratedApp3-${Date.now()}`)
const workingCopy = await app.createWorkingCopy();
const domainModelInterface = workingCopy.model().allDomainModels().filter(dm => dm.containerAsModule.name === "MyFirstModule")[0];
const loadedDomainModel = loadAsPromise(domainModelInterface);
generate(loadedDomainModel, workingCopy.model()); //call the generated JavaScript here
try {
const revision = await workingCopy.commit();
console.log(`Successfully committed revision: ${revision.num()}. Done.`)
} catch (error) {
console.error('Something went wrong:', error);
}
}
main();
//The generated code
function generate(domainModel1, model) {
}
Execute the script. You should have a new project with the generated entities.
Instead of creating a new project, you can also reuse an existing project or even an existing online working copy.