The Vue API client fetches necessary information from the server and generates a .csv file with accurate headers and IDs. However, the data retrieved is incomplete

Check out my code repository here: https://github.com/d0uble-happiness/discogsCSV

App.vue

<template>
    <div>
        <button @click="downloadSampleInputFile">Download basic sample file</button>
    </div>

    <div>
        <button @click="createSampleInputFile">Download random sample file</button>
    </div>

    <div>
        <FileUpload @file="setFile" />
    </div>

    <div>
        <p v-for="row of data" :key="row">
            {{ row }}
        </p>
    </div>

</template>

<script lang="ts">
import { defineComponent } from 'vue';
import FileUpload from '@/components/FileUpload.vue';
import { fetchRelease, parseCsvToArray } from '@/parser';
import { prepareDownload } from './components/PrepareDownload';
import { downloadSampleInputFile } from './components/DownloadSampleInputFile';
import { createSampleInputFile } from './components/CreateSampleInputFile';

export default defineComponent({
    name: 'App',
    components: {
        FileUpload
    },
    data() {
        return {
            data: null as null | string[],
            createSampleInputFile,
            downloadSampleInputFile
        }
    },
    methods: {
        async setFile(file: File) {
            this.data = await parseCsvToArray(file)
            console.log(this.data)
        },
        async fetchReleases(idList: string[]) {
            try {
                const data = await fetchRelease(idList)
                console.log('Fetched data from Discogs', data)
                return data
            } catch (err) {
                console.log('Failed fetching releases', err)
            }
        },
        async downloadCSV(data: any[]) {
            prepareDownload(data)
        },
    },
    watch: {
        data(data) {
            this.fetchReleases(data)
            this.downloadCSV(data)
        }
    },
});
</script>

FetchRelease.ts

import { DiscogsClient } from '@lionralfs/discogs-client'
import { processReleaseData } from './ProcessReleaseData'

export default {
  name: 'FetchRelease',
  methods: {
    fetchRelease
  }
}

const db = new DiscogsClient().database()

async function fetchRelease(releaseId: string): Promise<any[] | { error: string }> {
  try {
    const { data } = await db.getRelease(releaseId)
    return processReleaseData(releaseId, data)
  } catch (error) {
    return {
      error: `Release with ID ${releaseId} does not exist`
    }
  }
}

ProcessReleaseData.ts

import { type GetReleaseResponse } from '@lionralfs/discogs-client/lib/types'

export default {
  name: 'ProcessReleaseData',
  methods: {
    processReleaseData
  }
}

...
(contents omitted for brevity)
...

Answer №1

Seems like you forgot to assign the content retrieved in fetchReleases() to this.data.

    async fetchReleases(idList: string[]) {
        try {
            const data = await fetchRelease(idList)
            console.log('Data fetched from Discogs', data)
            this.data = data      // <--- data displayed in the view
            return data
        } catch (err) {
            console.log('Failed to fetch releases', err)
        }
    },

If you assign this.data, you will be able to see the data, though I'm not completely clear on how your process should work.

For future reference, utilizing the Composition API (<script setup>) may offer better readability and maintenance compared to the older Options API. It would streamline the use of the data identifier in your case.

Updated solution:

In your current code, data was handling input and output without a clear indication of the expected input format. Assuming your sample file contains 5 numbers (no header, not quite a CSV), I transitioned to the Composition API and separated data into inputData and outputData. This allows easier monitoring for their specific roles using watch.

You can eliminate the use of inputData entirely if you only plan to utilize the input in setFile(), but the rudimentary sample data doesn't provide much direction. The "random sample" wasn't functional from your repository.

App.vue

<script setup lang="ts">

import { ref, watch } from 'vue'
import FileUpload from '@/components/FileUpload.vue';
import { fetchRelease, parseCsvToArray } from '@/parser';
import { prepareDownload } from './components/PrepareDownload';
import { downloadSampleInputFile } from './components/DownloadSampleInputFile';
import { createSampleInputFile } from './components/CreateSampleInputFile';

const inputData = ref<string[]>([])
const outputData = ref<null | any[]>(null)

async function setFile(file: File) {
  inputData.value = await parseCsvToArray(file)
  console.log(inputData.value)
}

async function fetchReleases(idList: string[]) {
  try {
    const data = await fetchRelease(idList)
    console.log('Data fetched from Discogs', data)
    outputData.value = data
    return data
  } catch (err) {
    console.log('Failed to fetch releases', err)
  }
}

async function downloadCSV(data: any[]) {
  prepareDownload(data)
}

watch(inputData, newValue => {
  fetchReleases(newValue)
})

watch(outputData, newValue => {
  if (newValue) {
    downloadCSV(newValue)
  }
})

</script>

<template>
  <div>
    <button @click="downloadSampleInputFile">Download basic sample file</button>
  </div>

  <div>
    <button @click="createSampleInputFile">Download random sample file</button>
  </div>

  <div>
    <FileUpload @file="setFile" />
  </div>

  <div>
    <p v-for="row of outputData" :key="row">
      {{ row }}
    </p>
  </div>
</template>

Modified this line in parser.ts

export async function fetchRelease(releaseIds: string[]): Promise<any[]> {

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to include a required condition in a select element in vue.js 2?

This is how my Vue component looks: <template> <select class="form-control" v-model="selected" required @change="changeLocation"> <option v-for="option in options" v-bind:value="option.id" >{{ option.name }}</option>&bs ...

Refreshing the v-model in a child component

Within my parent component, the code structure is similar to this: <template> <ProductCounter v-model="formData.productCount" label="product count" /> </template> <script setup> const initialFormData = { ...

Deploying a Vue.js project for launch

When uploading my Vue.js project to a production server, must I update all the paths for photos, PHP files, and database connection files each time? Is there a more convenient or efficient method available? ...

Show targeted information from the array using the respective identifier

Is it feasible to exhibit data from a Vuex store array in a unique manner, comparable to the illustration provided below: <template> <div> <h1>{{this.$store.state.data.title}}</h1> <p>{{this.$store.state.da ...

What is the best way to retrieve the global styles.scss file from the assets folder for privacy, legal, and conditions pages

I have a static page called terms.html located at: $PROJECT_ROOT/src/assets/html/terms.html In addition, my global styles (used by all components) are found at: $PROJECT_ROOT/src/styles.scss To include the static html file in a component, I use the fol ...

Issue encountered when attempting to chain promises with async/await functionality

Here is my current code snippet: await enterName(); await enterCity(); await submit(); async enterName() { element.sendKeys('name'); } async submit() { element.submit(); waitForAngular(); } The problem I am facing is that when calling the subm ...

Sending various kinds of generic types to React component properties

Currently, my team and I are working on a TypeScript/React project that involves creating a versatile 'Wizard' component for multi-step processes. This Wizard acts as a container, receiving an array of 'panel' component properties and p ...

Tips for reducing redundant API requests while using NgRx

I'm facing an issue with my application that has 2 menu items; Teams and Players. Every time I switch between them, an unnecessary API call is made even though the data is already stored. Here is the effects file: loadTeams$ = createEffect(() => { ...

Creating a connection object for MySql2 in TypeScript within a class

I'm still a beginner when it comes to TypeScript, so I often stumble over simple things. Initially, I had no issues creating a database connection using the code snippet below that was not placed inside a class: const mysql = require('mysql2&apos ...

Having trouble setting up nginx in a container to reach a custom path location for a built vue app? If you're encountering a 404 error, here's how

I currently have a setup using Docker Swarm with a main nginx container that is accessible on ports 443 and 80. This nginx container acts as a proxy to a backend node application and a vue cli application housed within another nginx container. The setup is ...

Struggling to get the Vue.js + TypeScript + RequireJS stack functioning properly post Vue.js 2.5 upgrade

I am currently working on a project that uses the Vue.js 2.4 + TypeScript + RequireJS stack and I need to upgrade it to the latest version of Vue.js. However, after making the necessary changes according to the documentation, the upgrade breaks the project ...

The child component fails to inherit the data types provided by the parent component

I am currently working on setting up a dynamic table that will receive updates from the backend based on actions taken, which is why I need to pass the endpoint and response model. When I try to nest and pass the response type, it seems to get lost in the ...

Using props in the v-bind:src directive with Vue - a comprehensive guide!

I have a Vue application with a Block component that needs to display an image. The Block component is used multiple times in the App component, each time passing a value to determine which image src to choose from an array. When I try to print {{ this.Im ...

Type of condition based on function parameter values

I am facing a challenge where I need to merge two separate Typescript methods into one with the same name getDevice. The first method only requires a number input to return a Device, or null if no device is found: protected getDevice(deviceId: number): Dev ...

Tips for navigating between tabs without using the next button in Vue.js with vue-form-wizard

I am currently working on creating tabs in vuejs using the vue-form-wizard plugin. I have encountered an issue where I am unable to directly navigate from the first tab to the second or third tab by clicking on the tab for the first time. However, once all ...

Can Vue 3 Teleport only function to transport elements outside of the Vue environment?

Vue 3 introduces the Teleport feature, replacing the portal-vue plugin in Vue 2. However, I encountered an issue where it seems impossible to teleport a component to a place controlled by Vue within the app itself. It only seemed to work when porting compo ...

Improving Vue Component on Navigation

I am facing an issue with my navbar where I have two versions. Version 1 features a white text color, while Version 2 has black text. The need for two versions arises due to some pages having a white background, hence the requirement for black text. Bot ...

"Encountering issues with Angular2's FormBuilder and accessing nested object properties,

As I dip my toes into TypeScript and Angular2, I find myself grappling with a nested object structure in an API. My goal is to align my model closely with the API resource. Here's how I've defined the "Inquiry" model in TypeScript: // inquiry.ts ...

Utilizing TypeScript with React to dynamically select which component to render

My task seemed simple at first: to render a React component based on its name/type. Here is an example of how it is used: // WidgetsContainer.ts // components have a difference in props shape! const componentsData = [ { type: 'WIDGET_1', ...

Utilizing Typescript with Next.js API to limit the NextApiRequest query parameter to only accept string types

Is it possible to restrict the req.query in NextJS NextApiRequest to only accept string types instead of string | string[]? For instance, if someQueryParam is currently of type string | string[], but I need it to be just a string. export default async fun ...