0

I try like this :

const actions = {
    getData ({ commit }, payload) {
      const params = {}
      if(payload) {
        if (payload.dateFrom) { params.date_from = payload.dateFrom }
        if (payload.dateTo) { params.date_to = payload.dateTo}
      }
      axios
        .get(`${api}/reports/list`, {params})
        .then(r => r.data)
        .then(res => {
          console.log(res)
        })
    }
}

If I console.log(payload), the result like this :

{from: '2022-07-01', to: '2022-07-30'}

payload is optional

My code is working. But I want to know if there is a more concise way to express it.

  • Looking for a _"better way"_ is inviting opinion which makes this off-topic for StackOverflow. If what you've got works, there isn't a problem to solve here – Phil Aug 19 '22 at 00:16
  • It's unknown what's the definition of a better way in this case. undefined params are omitted, but it's unknown what are possible values of `from` and `to` – Estus Flask Aug 19 '22 at 00:30

4 Answers4

2

You can conditional add property to object like this:

const actions = {
  getData({ commit }, payload) {
    const params = {
      ...(payload?.dateFrom && {
        date_from: payload.dateFrom
      }),
      ...(payload?.dateTo && {
        date_to: payload.dateTo
      })
    };
    axios
      .get(`${api}/reports/list`, { params })
      .then((r) => r.data)
      .then((res) => {
        console.log(res);
      });
  }
};
Hoàng Huy Khánh
  • 1,071
  • 8
  • 16
  • 1
    TIL that spreading `undefined` results in an empty object. You might want to use some optional chaining in case `payload` itself is `undefined`... `payload?.dateFrom` – Phil Aug 19 '22 at 04:06
0

One idea is to default the param, then conditionally add its props, like...

getData ({ commit }, payload={}) {
  const params = {
    ...(payload.from ? {from: payload.from}: {}),
    ...(payload.to ? {to: payload.to}: {}),
  }
  axios
    .get(`${api}/reports/list`, {params})  // etc

That's still a little bit clumsy conditional inclusion of key-value pairs. Another idea, since it's really a kind of pick, you could code that explicitly (and reuse it elsewhere)...

// pick, thanks to https://stackoverflow.com/a/56592365/294949
function pick(obj={}, keys=[])
  return Object.fromEntries(
    keys.filter(key => key in obj).map(key => [key, obj[key]])
  );
}

Then getData is...

getData ({ commit }, payload) {
  const params = pick(payload, ['from', 'to']);
  axios
    .get(`${api}/reports/list`, {params})  // etc

edit if the key names will change, then it's not a pick. The first idea still works, and given the switch is probably close to minimal code...

getData ({ commit }, payload={}) {
  const params = {
    ...(payload.dateFrom ? {date_from: payload.dateFrom}: {}),
    ...(payload.dateTo ? {date_to: payload.dateTo}: {}),
  }
  axios
    .get(`${api}/reports/list`, {params})  // etc
danh
  • 62,181
  • 10
  • 95
  • 136
  • @positivedeveloper, since the key names are different, the "pick" idea is no longer useful, but the first one still works. See the edit, at the bottom, where the new key names are accounted for. (I left the original answer in case future readers have a question like the original) – danh Aug 19 '22 at 04:21
-1

try this.

  getTest({ commit }, { from = undefined, to = undefined }) {
    axios
      .get(`api/reports/list`, { params: { from, to } })
      .then((r) => r.data)
      .then((res) => {
        console.log(res);
      });
  }

so when you want to use the action you can do these

this.$store.dispatch("getTest", { from: 121 });

this.$store.dispatch("getTest",{}); //at least an empty Object

-1

Maybe you can try this:

const actions = {
    getData ({ commit }, payload) {
      const params = { ...payload }
      axios
        .get(`${api}/reports/list`, { params })
        .then(r => r.data)
        .then(res => {
          console.log(res)
        })
    }
}
Adams Tsui
  • 34
  • 4