skip to Main Content

I need a method that creates a Quasar Table column definition dynamically. The method below works, however, I believe that using a for loop in place of the long switch statement is a better solution.

How do I write a for loop that produces the same result as the following:

const createTableColumns = (numberOfColumns: number) => {
  const tableCols: QTableProps["columns"] = [];
  const numberOfColumnsStr = numberOfColumns.toString();

  switch (numberOfColumnsStr) {
    case "15":
      tableCols.push({
        name: "15",
        align: "center",
        label: "15",
        field: (row) => row.fifteen.value,
        format: (val, row) =>
          row.fifteen.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "14":
      tableCols.push({
        name: "14",
        align: "center",
        label: "14",
        field: (row) => row.fourteen.value,
        format: (val, row) =>
          row.fourteen.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "13":
      tableCols.push({
        name: "13",
        align: "center",
        label: "13",
        field: (row) => row.thirteen.value,
        format: (val, row) =>
          row.thirteen.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "12":
      tableCols.push({
        name: "12",
        align: "center",
        label: "12",
        field: (row) => row.twelve.value,
        format: (val, row) =>
          row.twelve.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "11":
      tableCols.push({
        name: "11",
        align: "center",
        label: "11",
        field: (row) => row.eleven.value,
        format: (val, row) =>
          row.eleven.isSlected ? `** ${val} **` : `${val}`,
        sortable: false,
      });
    case "10":
      tableCols.push({
        name: "10",
        align: "center",
        label: "10",
        field: (row) => row.ten.value,
        format: (val, row) => (row.ten.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "9":
      tableCols.push({
        name: "9",
        align: "center",
        label: "9",
        field: (row) => row.nine.value,
        format: (val, row) => (row.nine.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "8":
      tableCols.push({
        name: "8",
        align: "center",
        label: "8",
        field: (row) => row.eight.value,
        format: (val, row) => (row.eight.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "7":
      tableCols.push({
        name: "7",
        align: "center",
        label: "7",
        field: (row) => row.seven.value,
        format: (val, row) => (row.seven.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "6":
      tableCols.push({
        name: "6",
        align: "center",
        label: "6",
        field: (row) => row.six.value,
        format: (val, row) => (row.six.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "5":
      tableCols.push({
        name: "5",
        align: "center",
        label: "5",
        field: (row) => row.five.value,
        format: (val, row) => (row.five.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "4":
      tableCols.push({
        name: "4",
        align: "center",
        label: "4",
        field: (row) => row.four.value,
        format: (val, row) => (row.four.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });
    case "3":
      tableCols.push({
        name: "3",
        align: "center",
        label: "3",
        field: (row) => row.three.value,
        format: (val, row) => (row.three.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });

    case "2":
      tableCols.push({
        name: "2",
        align: "center",
        label: "2",
        field: (row) => row.two.value,
        format: (val, row) => (row.two.isSlected ? `** ${val} **` : `${val}`),
        sortable: false,
      });

    case "1":
      tableCols.push({
        name: "1",
        align: "center",
        label: "1",
        field: (row) => row.name,
        format: (val, row) => `${val}`,
        sortable: false,
      });

      break;
    default:
      console.error(`Game: createTableColumns DEFAULT!!!`);
  }

  tableCols.sort((a, b) => parseInt(a.name) - parseInt(b.name));
  return tableCols;
};

I’ve tried this:

const tableCols2: QTableProps["columns"] = [];
for (let colIndex = 0; colIndex < numberOfColumns; colIndex++) {
  const rowKeyArray = [
    "NotUsed",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine",
    "ten",
    "eleven",
    "twelve",
    "thirteen",
    "fourteen",
    "fifteen",
  ];
  const colNumber: number = colIndex + 1;
  const rowKey: string = rowKeyArray[colIndex];
  const myObj = {
    name: colNumber.toString(),
    align: "center",
    label: colNumber.toString(),
    field: (row) => row[rowKey].value,
    format: (val, row) => (row[rowKey].isSlected ? `** ${val} **` : `${val}`),
    sortable: false,
  };

  tableCols2.push(myObj);
}

2

Answers


  1. I guess you can do a similar implementation but using objects instead:

    let keyMap = {
      '1': 'one',
      '2': 'two',
      // ...
    }
    let colIndex: keyof typeof keyMap;
    const tableCols2: QTableProps["columns"] = [];
    
    for (colIndex in keyMap) {
      const rowKey: string = keyMap[colIndex];
      const myObj = {
        name: colIndex,
        align: "center",
        label: colIndex,
        field: (row) => row[rowKey].value,
        format: (val, row) => (row[rowKey].isSelected ? `** ${val} **` : `${val}`),
        sortable: false,
      };
    
      tableCols2.push(myObj);
    }
    
    Login or Signup to reply.
  2. To simplify matters, have a look at this (vanilla JS) potential solution:

    const createTableColumns = (numberOfColumn) => {
      const englishNames = "zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen".split(',');
      if( numberOfColumn < 1 || numberOfColumn >= englishNames.length) throw("invalid number of columns: " + numberOfColumn);
      
      const tableCols = [];
      for(let col = numberOfColumn; col >= 1; col--) {
        const colAsString = col.toString();
        const colAsEnglish = englishNames[col];
        const obj = {
            name: colAsString,
            align: "center",
            label: colAsString,
            field: (row) => row[colAsEnglish].value,
            format: (val, row) => (row[colAsEnglish].isSlected ? `** ${val} **` : `${val}`),
            sortable: false,
          };
        tableCols.push(obj);
      }
      return tableCols;
    }
    

    Note:

    • The switch statement in the working code contains no break statements: every matched number of columns falls through to the next lower number of columns. Hence objects are pushed onto tableCols in reverse order of row columns.

    • In the code above, the for loop uses let and const declarations to ensure column values are in the environment record created for each iteration. Hence the colAsString and colAsEnglish values used in the function methods of obj (field and format) are particular to the loop iteration they were defined in.

    Now some issues for your consideration:

    1. Naming the row column properties with English names of numbers creates a headache and could be difficult to maintain. Using calculated column property names, say for one based names, "C1", "C2", … "C15", would be simpler.
    2. The question title is a bit dubious: an object whose value is a function is a function.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search