I've been using monday's react starter/example and here are some findings that may be useful to others.
If you want to see me explaining some aspects of how I'm doing development on monday.com apps to another developer, please take a look here (20 mins) -- https://www.youtube.com/watch?v=7N8ArOz2Su4 -- it's a bit sweary, but that's just me, sorry.
When running a dev version of the app in the "test harness" (see later), you have to update the "Custom URL" every time you run npm run start
as it uses a randomised **********.ngrok.io
subdomain. It's free, what can you expect.
Use you own dedicated ngrok subdomain (paid) to prevent having to constantly update the ngrok URL whenever you restart working on the monday.com app
Modify package.json
and replace
"expose": "ngrok http 8301",
with
"expose": "ngrok http 8301 -subdomain yourdomain-example-monday-dev",
"expose:default": "ngrok http 8301",
npm run expose:default
is just there so I can remember the default settingsnpm run expose
now runs the app on a consistent URL
Then use https://yourdomain-example-monday-dev.ngrok.io as the base URL that you add in the custom URL field
e.g. https://yourdomain-example-monday-dev.ngrok.io/some-feature
.
By "test harness", I mean the development area e.g. at https://dsapps.monday.com/apps/manage/10026522/app_versions/10037594/app_features/10070035
When developing an item view, you select a board and then if you're lucky (I've only had this happen correctly once), you can select an item from which to test the feature.
If this even works, then you can't just check for res.data.context.instanceType === "item_view"
,
because the context is different for an item_view and a faked up item view
monday.listen("context", (res) => {
const context = res.data;
if (
context?.instanceType === "item_view" // a real item view
|| (context?.boardIds?.length === 1 && context?.itemIds?.length === 1) // in the "Custom URL" faked up item view
) {
let itemId, boardId;
if (context.boardIds.length === 1 && context.itemIds.length === 1) {
// in the "Custom URL" faked up item view
boardId = context.boardIds[0];
itemId = context.itemIds[0];
} else {
// in a real item view
itemId = context.itemId;
boardId = context.boardId;
}
...
}
});
When you create a new dashboard widget, in Edit Mode, you can specify:
- Board Picker: Without (Choose either your widget is based on boards and therefore the user needs to pick them, or not)
- Title: Without (Choose either your widget will get a title, or not)
I assume that this should mean that when you add the widget, it should not ask you to select a board before you go into Settings.
Also I'd imagine that "Title: Without" would mean that when the widget is added to the workdoc or dashboard, it would just show the widget, without a title at the top.
🔴 In both cases, this does not seem to be the case.
I created a new column of type "Long Text" to save a Mermaid Class Diagram and added the following text
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
Long Text sanitises this to:
classDiagram
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
and so breaks the diagram.
Here's the thing. You don't know that the sanitisation has occured until you reload the page and the column then updates from monday.com.
So when the text is pasted into a "Long Text" column, it performs a POST to https://dsapps.monday.com/boards/2580137377/batch_change_column_value with the contents of the column.
This sanitised the text saved to monday.com, but does not update the text you pasted into the field in the browser. Only after a subsequent browser full page reload does the text displayed in the field change to the sanitised version.
Trying to move this diagram to a "Text" column, this column type removes all new line character, so that's no good either
This also seems to work OK, with one massive caveat.
🔴 You cannot store any text in there that uses a new line character, as it will silently fail when you do this:
const monday = mondaySdk();
const someKey = "someKey";
const someVal = "Lorem Ipsum 123\n\nxxxx";
monday.storage.instance.setItem(someKey, someVal).then((res) => {
console.log(res); // --> says it saved OK. It did not.
});
- More details in Findings from initial attempts at using
monday.storage
If you've made it this far, then I can recommend
- Using your own pro ngrok account
- Creating a dev version of your app (e.g. named Your App Name DEV) and using your dev ngrok system
as the published version with the published URL
(with e.g.
https://yourdomain-example-monday-dev.ngrok.io/some-feature
) - Do your development on the published dev version of your app (e.g. named Your App Name DEV)
- Watch out if using
monday.storage
with new line characters - Beware input sanitisation on "Long Text" columns
Why?
- Updating the "Custom URL" of the app every time you restart the app is tedious
- A consistent app URL is easier to remember
- Developing on a real, live app means that the pitfalls and limitations of the "test harness" are removed