0

I am working on modifying a section of a form. There I will fetch the data using that content id from an api and then I want to map the returned data to form an array in data, so I can patch it more easily.

Here is my .vue component:

<template>
  <div>
    <b-field label="Activity ID" message horizontal>
      <b-input
        v-model="form.id"
        placeholder="65587ghfd7654654"
        required
        disabled
      />
    </b-field>
    <b-field label="Activity Name" message horizontal>
      <b-input
        v-model="form.package_name"
        placeholder="eg. Dubai Desert Safari evening with BBQ Dinner"
        required
      />
    </b-field>
    <b-field label="Activity Slug" message horizontal>
      <b-input
        v-model="form.slug"
        placeholder="eg. Dubai-Desert-Safari-evening-with-BBQ-Dinner"
        required
      />
    </b-field>
    <b-field
      label="Short Summary"
      message="Your question. Max 500 characters"
      horizontal
    >
      <b-input
        v-model="form.summary"
        type="textarea"
        placeholder="short summary about activity"
        maxlength="500"
        required
      />
    </b-field>
    <div
      v-for="(item, index) in form.otherinfos.highlightspoints"
      :key="item"
      class="ttc-grid ttc-grid-cols-4 ttc-gap-4"
    >
      <div class="ttc-col-span-3">
        <b-field :label="`# ${index + 1}`" message horizontal>
          <b-input
            v-model="form.otherinfos.highlightspoints[index]"
            placeholder="eg. Dubai Desert Safari evening with BBQ Dinner"
            required
          />
        </b-field>
      </div>
      <div class="ttc-col-span-1">
        <b-button
          v-show="
            index || (!index && form.otherinfos.highlightspoints.length > 1)
          "
          class="ttc-bg-green"
          @click="remove(`highlights`, index)"
        >
          Remove
        </b-button>
        <b-button
          v-show="index == form.otherinfos.highlightspoints.length - 1"
          class="ttc-bg-red"
          @click="add(`highlights`)"
        >
          Add fields
        </b-button>
      </div>
    </div>
    <b-field horizontal>
      <b-field grouped>
        <div class="control">
          <b-button native-type="submit" type="is-primary">Submit</b-button>
        </div>
        <div class="control">
          <b-button type="is-primary is-outlined" @click="reset">
            Reset
          </b-button>
        </div>
      </b-field>
    </b-field>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isLoading: false,
      form: {
        package_name: null,
        id: '765hjgf987656754',
        slug: null,
        summary: null,
        otherinfos: {
          highlightspoints: [
            'eg. add highlights',
            'eg. add highlights',
            'eg. add highlights',
            'eg. add highlights',
          ],
        },
        price: {
          currencyCode: 'EUR',
          amount: '35.00',
        },
      },
    }
  },
  async fetch() {
    const data = await fetch(`${this.backendApi}/tours/gettourbyuniqueid`, {
      // publicRuntime used here, more info > https://stackoverflow.com/a/67705541/8816585
      method: 'post',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        uniqueid: 'e45d3b76-a3d9-4a97-9780-977db5e328c2',
      }),
    }).then((res) => res.json())
  },

  methods: {
    add(tabkey) {
      if (tabkey === 'highlights') {
        this.form.otherinfos.highlightspoints.push('')
      }
    },
    remove(tabkey, index) {
      if (tabkey === 'highlights') {
        this.form.otherinfos.highlightspoints.splice(index, 1)
      }
    },
  },
}
</script>

This is the response I get from the API:

{
  "price": {
    "currencyCode": "EUR",
    "amount": "35.00"
  },
  "otherinfos": {
    "highlightspoints": [
      "Tackle the high red dunes of the Arabian desert and enjoy the magic of desert culture in this evening safari!",
      "Enjoy activities such as camel riding, henna tattoos, and even photograph yourself in traditional dress",
      "Test your skills on a sand board down the slopes and experience the thrill of a 4x4 ride on the sand dunes",
      "Watch a Tanoura and belly dancing show while enjoying a barbecue dinner in the desert encampment",
      "A professional English speaking Safari guide will aid you on your adventure!"
    ]
  },
  "package_name": "Dubai Desert Safari Red Dune: BBQ, Camel Ride & Sandboarding",
  "slug": "Dubai-Desert-Safari-Red-Dune:-BBQ-Camel-Ride-and-Sandboarding",
  "summary": "Escape Dubai and drive across the Red Arabian Desert in a 4WD vehicle. Enjoy the sunset, sandboarding, camel ride and visit the camel firm. Choose the 4-hour program or the 7-hour program with the addition of a BBQ dinner.",
  "id": "616b498c6b667513d9ec54f6"
}

I want to map this response to data properties, so form can be populated with these datas and then if any changes will be made, we will patch it by API.

kissu
  • 40,416
  • 14
  • 65
  • 133
imthegrv
  • 369
  • 7
  • 17
  • You will need a `computed` here if you want it to be reactive afterwards. – kissu Dec 18 '21 at 10:12
  • @kissu , thanks for response, i am still confused on how to move forward with it, can you guide me here with a little more. – imthegrv Dec 18 '21 at 10:54
  • but i want to understand, you said computed in your earlier comment, how can we work on that? – imthegrv Dec 20 '21 at 09:51
  • If you're updating your data based on an action (clicking on a button, navigating to a specific path etc...), you don't really need to bother with this concept. You just cannot have a property in your `data` object being re-computed if it relies on another state value eg: "fullName: `${this.firstName} ${this.lastName}`". For that, you'll need a `computed`. Still, you're not in that use-case here, so it's not a big deal. Please read [this one](https://vuejs.org/v2/api/#data) to get more info on `data()`. – kissu Dec 20 '21 at 10:01

1 Answers1

1

That one does not work?

<template>
  <div>
    <b-field label="Activity ID" message horizontal>
      <b-input
        v-model="form.id"
        placeholder="65587ghfd7654654"
        required
        disabled
      />
    </b-field>
    <b-field label="Activity Name" message horizontal>
      <b-input
        v-model="form.package_name"
        placeholder="eg. Dubai Desert Safari evening with BBQ Dinner"
        required
      />
    </b-field>
    <b-field label="Activity Slug" message horizontal>
      <b-input
        v-model="form.slug"
        placeholder="eg. Dubai-Desert-Safari-evening-with-BBQ-Dinner"
        required
      />
    </b-field>
    <b-field
      label="Short Summary"
      message="Your question. Max 500 characters"
      horizontal
    >
      <b-input
        v-model="form.summary"
        type="textarea"
        placeholder="short summary about activity"
        maxlength="500"
        required
      />
    </b-field>
    <div
      v-for="(item, index) in form.otherinfos.highlightspoints"
      :key="item"
      class="ttc-grid ttc-grid-cols-4 ttc-gap-4"
    >
      <div class="ttc-col-span-3">
        <b-field :label="`# ${index + 1}`" message horizontal>
          <b-input
            v-model="form.otherinfos.highlightspoints[index]"
            placeholder="eg. Dubai Desert Safari evening with BBQ Dinner"
            required
          />
        </b-field>
      </div>
      <div class="ttc-col-span-1">
        <b-button
          v-show="
            index || (!index && form.otherinfos.highlightspoints.length > 1)
          "
          class="ttc-bg-green"
          @click="remove(`highlights`, index)"
        >
          Remove
        </b-button>
        <b-button
          v-show="index == form.otherinfos.highlightspoints.length - 1"
          class="ttc-bg-red"
          @click="add(`highlights`)"
        >
          Add fields
        </b-button>
      </div>
    </div>
    <b-field horizontal>
      <b-field grouped>
        <div class="control">
          <b-button native-type="submit" type="is-primary">Submit</b-button>
        </div>
        <div class="control">
          <b-button type="is-primary is-outlined" @click="reset">
            Reset
          </b-button>
        </div>
      </b-field>
    </b-field>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isLoading: false,
      form: {
        package_name: null,
        id: '765hjgf987656754',
        slug: null,
        summary: null,
        otherinfos: {
          highlightspoints: [
            'eg. add highlights',
            'eg. add highlights',
            'eg. add highlights',
            'eg. add highlights',
          ],
        },
        price: {
          currencyCode: 'EUR',
          amount: '35.00',
        },
      },
    }
  },
  async fetch() {
    const dataFetchedFromApi = await fetch(
      `${this.backendApi}/tours/gettourbyuniqueid`,
      {
        // publicRuntime used here, more info > https://stackoverflow.com/a/67705541/8816585
        method: 'post',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          uniqueid: 'e45d3b76-a3d9-4a97-9780-977db5e328c2',
        }),
      }
    ).then((res) => res.json())

    this.form = dataFetchedFromApi // << update the local data here, after the HTTP call
  },

  methods: {
    add(tabkey) {
      if (tabkey === 'highlights') {
        this.form.otherinfos.highlightspoints.push('')
      }
    },
    remove(tabkey, index) {
      if (tabkey === 'highlights') {
        this.form.otherinfos.highlightspoints.splice(index, 1)
      }
    },
  },
}
</script>
kissu
  • 40,416
  • 14
  • 65
  • 133