Creating multiple columns?

3 columns should be created on one board:

mon-columns

But only 1 or 2 columns get added to the board, inconsistently:

1-col 2-cols

code:

this.createBoard("Test", null).then(boardId => {
    const { columnNames } = this.state;
    columnNames.forEach(title => {
        this.createColumn(boardId, title, "text");
    })
})

async createColumn(boardId, title, type) {
    const query = `mutation { 
      create_column (board_id: ${boardId}, title: ${title}, column_type: ${type}) {
        id }}`;
    await monday.api(query).then(res => {
        console.log(`col created: ${JSON.stringify(res.data)}`);
    });
};

Hey @supernova,

Let me check in with the team on this - more on this soon!

Best,
Daniel

1 Like

Hey @dsilva , I figured it out :slight_smile:

Solution:

Add delay between each column creation with setTimeout so that the calls are made consecutively

  componentDidMount() {
      this.addColumns();
  }

  addColumns = () => {
      this.createBoard("Test", "share").then((boardId) => {
          this.addColumn(boardId, 'text');
          setTimeout(() => { this.addColumn(boardId, 'text') }, 2000);
          setTimeout(() => { this.addColumn(boardId, 'date') }, 3000);
      })
  }

  addColumn = (boardId, type) => {
      const { columnTitles, colIndex } = this.state;
      if (colIndex < columnTitles.length) {
          this.setState({ colIndex: colIndex + 1 }, () => {
              this.createColumn(boardId, columnTitles[colIndex], type);
          });
      }
  }

Or more concisely:
columnTitles: [
  {title: "url", type:"text"}, 
  {title: "name", type: "text"},
  {title: "date", type :"date"}
]

createBoardWithColumns = (boardName, boardType) => {
    this.createBoard(boardName, boardType).then(boardId => {
       let offset = 0;
       this.state.columnTitles.forEach(col => {
         setTimeout(() => {
         this.createColumn(boardId, col.title, col.type)
       }, 1000 + offset);
       offset += 1000;
       })
    })
}

Hey @supernova,

Apologies for the delay here - but amazing job figuring it out! Giving those calls a bit of breathing room so they can be made consecutively should do the trick - but if you run into any other issues please let us know :slight_smile:

-Daniel

1 Like

That’s awesome! you got it!

Take my suggestion with a grain of salt especially since you’ve already got it, but I still want to throw it out there just in case it’s useful.
I think you should take advantage of the async / await you already have. I did it locally and everything still works.

So instead of using setTimeout, you can use:

this.state.columnTitles.forEach(async col => {
   await this.createColumn(boardId, col.title, col.type)
})
2 Likes

Hi :hot_pepper: , I just tested it on my end but can’t get it to work for some reason. It’s still adding only 1 or 2 of the 3 columns to the board like before :hushed:

1 Like

Hey @pepperaddict - thanks for jumping in here and sharing a different way to approach this, that’s awesome!

@supernova what I think is happening here is you are hitting the complexity rate per minute cap of our API when making those calls, which is why the setTimeout solution works as well. By adding a delay between the calls, the queries are more spread out and they are less likely to hit the limit. Does that make sense?

I hope that helps get this to work in the most efficient way possible :slight_smile:

-Alex

1 Like

@AlexSavchuk yes, but what I meant was setTimeout works for me but async/await doesn’t…

2 Likes

@supernova

Thank you for clarifying further! I think the async/await doesn’t work in this case because the calls are still running too close to each other - either way, I’m glad that adding timeouts would work for your use case.

-Alex

2 Likes

But I’m confused cause it worked for :hot_pepper: …
Please confirm @pepperaddict? cause async/await is obv the cleaner solution if I could only get that to work instead

1 Like

Hey! I was wrong. Sorry.

I only counted for the console log as the success and jumped at that, but when previewing my actual Monday app, the columns didn’t show. Bummer. Sorry about that!

So, I tried a different method. I think the problem more aligns with forEach() as it fires them all at once and instead of a one-at-a-time thing which is what we want. I tried a for loop and that works. haha. I tested it twice and have seen the three columns show each of those times. Before that, I’ve tried .map() with Promise.all and that didn’t work. columnTitles.reduce() didn’t work either… but a generic for loop does. :woman_shrugging:

      const boardId = data.data.create_board.id
      for (const col of columnTitles) {
        await createColumn(boardId, col.title, col.type)
      }

If that doesn’t work, it may be because of the other stuff I added with it. My code is in functional component so it’s a bit different than your class components.


  const createColumn = async (boardId, title, type) => {
    const query = `mutation { 
      create_column (board_id: ${boardId}, title: ${title}, column_type: ${type}) {
        id }}`;
    return await monday.api(query).then(async (res) => {
      await console.log(`col created: ${JSON.stringify(res.data)}`);
    });
  };

  const createBoard = async (e) => {
    const query = `mutation {
    create_board (board_name: "wuddup", board_kind: public) {
    id
    }
    }`;
    return await monday.api(query).then((boardId) => boardId);
  };
  const createBoardWithColumns = async (boardName, boardType) => {
    const columnTitles = [
      { title: "url", type: "text" },
      { title: "name", type: "text" },
      { title: "date", type: "date" },
    ];

    await createBoard(boardName, boardType).then(async (data) => {
      const boardId = data.data.create_board.id;
      for (const col of columnTitles) {
        await createColumn(boardId, col.title, col.type);
      }
    });
  };
1 Like

Ahh ok np I see, yup in this case the log in console is misleading. That’s why I created this thread haha I also tried it before with Promise.all & .map ( sorry for making you repeat the same mistakes I did :stuck_out_tongue_closed_eyes: ) - should’ve been clearer in my initial post as it seems like it’s stirred up quite a bit of confusion here!

Interesting that a simple for loop does the trick…I haven’t tested it yet but I’ll take your word for it :+1: I appreciate the time you took to follow up & recreate this on your end :sparkles: Thanks @pepperaddict <3

1 Like