Categories
Vue Answers

How to Force Download with GET Request using Axios?

Sometimes, we want to download files from responses made with GET requests.

In this article, we’ll look at how to download files from responses made with GET requests.

Force Download with GET Request using Axios

We can make the response always download by passing our response data into the Blob constructor.

For instance, we can write:

axios
  .get(`download-pdf`, {
    responseType: 'arraybuffer'
  })
  .then(response => {
    const blob = new Blob(
      [response.data],
      { type: 'application/pdf' }
    ),
    const url = window.URL.createObjectURL(blob);
    window.open(url) ;
  })

We make a GET request to the download-pdf endpoint to download our PDF.

We make sure that we specify that the responseType is 'arraybuffer' to indicate that it’s a binary file.

Then in the then callback, we get the response parameter, which has the data we want in the data property.

We pass that into the Blob constructor in an array.

And we specify the MIME type of the response data.

Then we create the URL that lets us download the file with createObjectURL .

Finally, we call window.open with the url to download the file.

We can also specify the file name of the downloaded file by making a small change in the then callback.

To do that, we write:

axios
  .get(`download-pdf`, {
    responseType: 'arraybuffer'
  })
  .then(response => {
    const blob = new Blob(
      [response.data],
      { type: 'application/pdf' }
    ),
    const link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = "file.pdf";
    link.click();
  })

Instead of creating an object URL directly, we create an invisible link first and set the file name as the download property of it.

Then we call click to download it.

Conclusion

We can make the response always download by passing our response data into the Blob constructor.

Categories
Vue Answers

How to Pass Down Vue Component Slots Inside Wrapper Component?

Sometimes, we want to pass down Vue component slots in a wrapper component.

In this article, we’ll look at how to pass down Vue component slots in a wrapper component.

How to Pass Down Vue Component Slots Inside Wrapper Component

To pass down slots in a wrapper component, we can loop through all the slots and pass them down to the child.

For instance, we can write:

<wrapper>
  <parent-table v-bind="$attrs" v-on="$listeners">

    <slot v-for="slot in Object.keys($slots)" :name="slot" :slot="slot"/>

    <template v-for="slot in Object.keys($scopedSlots)" :slot="slot" slot-scope="scope">
      <slot :name="slot" v-bind="scope"/>
    </template>

  </parent-table>
</wrapper>

We get the slots with the $slots variable.

Then we use Object.keys to get names of the slots so that we can loop through all of them and pass the name down.

Likewise, we can loop through the scoped slots with the $scopedSlots variables.

We get the keys the same way and loop through them with v-for the same way.

With Vue 2.6, the v-slot= directive is introduced to let is pass the slots down.

For instance, we can write:

<wrapper>
  <parent-table v-bind="$attrs" v-on="$listeners">
    <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
      <slot :name="slot" v-bind="scope"/>
    </template>
  </parent-table>
</wrapper>

We loop through the slot with v-for .

We get the scoped slots with the $scopedSlots variable.

slot is the slot name again.

This time, we pass it to the v-slot directive as a modifier to pass down the named slot.

scope has the scope from the scoped slot.

We use v-bind to get the scope.

And we

Alternatively, we can use render function to pass down the slots.

For instance, we can write:

render(h) {
  const children = Object.keys(this.$slots)
    .map(slot => h('template', { slot }, this.$slots[slot]))

  return h('wrapper', [
    h('parent-table', {
      attrs: this.$attrs,
      on: this.$listeners,
      scopedSlots: this.$scopedSlots,
    }, children)
  ])
}

We get the slots with the this.$slots property.

We call Object.keys to get the slot names.

And we call map on it to map the slot names to the template components.

And we pass in the slots name and the scope down,.

Then we return a wrapper component with the parent-table component with the listeners, attributes, and scoped slots and children as the children.

Conclusion

To pass down slots in a wrapper component, we can loop through all the slots and pass them down to the child.

Categories
Vue Answers

How to Pass Multiple Parameters to a Vuex Mutation?

Sometimes, we want to pass multiple parameters to a Vuex mutation.

In this article, we’ll look at how to pass multiple parameters to a Vuex mutation.

Passing Multiple Parameters to a Mutation with Vuex

To pass multiple parameters to action with Vuex, we can pass in an object as the payload.

For instance, we can create our mutation by writing:

mutations: {
  setToken(state, { token, expiration }) {
    localStorage.setItem('token', token);
    localStorage.setItem('expiration', expiration);
  }
}

We have an object as the second parameter.

It has the token and expiration properties.

Then we can invoke the mutation by writing:

store.commit('setToken', {
  token,
  expiration,
});

We invoke the setToken mutation with the token and expiration properties in an object as the 2nd argument.

Conclusion

To pass multiple parameters to action with Vuex, we can pass in an object as the payload.

Categories
React Native Answers

How to fix the React Native navigation paramlist never used error?

To fix the React Native navigation paramlist never used error, we add '@typescript-eslint/parser' into .eslintrc.

For instance, in .eslintrc, we write

{
  "parser": "@typescript-eslint/parser"
}

We also need to download ‘@typescript-eslint/parser’ in your dev dependencies

To do this, we run

npm i @typescript-eslint/parser --save-dev
Categories
React Native Answers

How to populate the right side of the navigation header with React Native?

To populate the right side of the navigation header with React Native, we set the screnOptions prop o

<Stack.Navigator>
  <Stack.Group
    screenOptions={({ route, navigation }) => ({
      headerRight: () => <Button onPress={() => navigation.navigate("Home")} />,
    })}
  >
    <Stack.Screen name="Home" component={HomeScreen} />
    <Stack.Screen name="Profile" component={ProfileScreen} />
  </Stack.Group>
  <Stack.Group screenOptions={{ presentation: "modal" }}>
    <Stack.Screen name="Settings" component={Settings} />
    <Stack.Screen name="Share" component={Share} />
  </Stack.Group>
</Stack.Navigator>;

to add the Stack.Group‘s screenOptions prop.

We set it to a function that has a button on the right by setting headerRight to a function that renders a Button.