0

I tried to apply architecture found here:

I don't succeed retrieving array of objects Release to be then be displayed inside component via v-list. I would like to extract the list of object from the returned promise. Not sure how to do this in Release.vue.

ReleaseApi.ts

import Axios from "axios";
import Release, {ReleaseDTO} from '@/models/Release';

interface RequestInterface {  
  map(arg0: (data: ReleaseDTO) => Release): Release[] | Promise<Release[]>;
  data: ReleaseDTO[]
}

export abstract class ReleasesApi {

private static instanceAxios = Axios.create({}); //baseURL: 'http://localhost:3000/'

  static async getAllReleases(): Promise<Release[]>{
    const response = await this.instanceAxios.get<RequestInterface>('api/releases');
    return response.data.map(data => new Release(data));
  }

}

Release.vue

<template>
    <h1>Releases</h1>
    <div v-if="loading">
      <h1>Asynchroneous called when mount state</h1>
        <v-list>
          <v-list-item :key="index" v-for="(release, index) in releases">
          {{release.name}} <br/>

          </v-list-item>
        </v-list>
    </div>
</template>
 
<script lang="ts">
import { defineComponent, ref,reactive,onMounted} from 'vue';
import { ReleasesApi  } from '../api/ReleasesApi'; 
import Release from '@/models/Release';
//https://github.com/kstraszewski/playground-vue/blob/class-based-fetching/src/views/Home.vue

export default defineComponent ({
setup (){

   let loading  = ref(false);
   let releases :any = ref([]);

  onMounted (  async () =>  {
       loading.value  = false;
       releases.value =  await ReleasesApi.getAllReleases();
       console.log(JSON.stringify(releases.value));
       loading.value  = true;

  })

   // expose to template
  return {loading,releases};

}
});

  </script>

Release.ts

export class ReleaseInterface{
  release_id?: number;
  date?: Date;
  name?: string;

}

export class ReleaseDTO implements ReleaseInterface{
  release_id?: number = 0;
  date?: Date = new Date(2012, 0, 1);
  name?: string = "";

}

export default class Release extends ReleaseDTO {

  constructor(dto: ReleaseDTO){
    super();
    Object.assign(this, dto);
  }

  get fullName(): string {
    return `${this.release_id}  ${this.name}`;
  }

}

Using :

let releases : Release[] | Promise<Release[] = ref([]);

ERROR Failed to compile with 1 error
4:52:53 PM

error in /home/jp/eclipse-workspace/Vue/scs/frontend/src/components/Release.vue.ts

[tsl] ERROR in /home/jp/eclipse-workspace/Vue/scs/frontend/src/components/Release.vue.ts(10,49) TS1005: '>' expected.

@ ./src/components/Release.vue?vue&type=script&lang=ts 1:0-327 1:0-327 1:328-644 1:328-644 @ ./src/components/Release.vue @ ./src/main.ts @ multi (webpack)-dev-server/client?http://192.168.226.145:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.ts

Issues checking in progress... ERROR in src/components/Release.vue:24:8 TS2322: Type 'Ref<never[]>' is not assignable to type 'Release[] | Promise<Release[]>'. Type 'Ref<never[]>' is missing the following properties from type 'Promise<Release[]>': then, catch, [Symbol.toStringTag], finally 22 | 23 | let loading = ref(false);

24 | let releases : Release[] | Promise<Release[] = ref([]); | ^^^^^^^^ 25 | 26 | onMounted ( async () => { 27 | loading.value = false;

ERROR in src/components/Release.vue:28:17 TS2339: Property 'value' does not exist on type 'Release[] | Promise<Release[]>'. Property 'value' does not exist on type 'Release[]'. 26 | onMounted ( async () => { 27 | loading.value = false;

28 | releases.value = await ReleasesApi.getAllReleases(); | ^^^^^ 29 | console.log(JSON.stringify(releases.value)); 30 | loading.value = true; 31 |

ERROR in src/components/Release.vue:29:44 TS2339: Property 'value' does not exist on type 'Release[] | Promise<Release[]>'. Property 'value' does not exist on type 'Release[]'. 27 | loading.value = false; 28 | releases.value = await ReleasesApi.getAllReleases();

29 | console.log(JSON.stringify(releases.value)); | ^^^^^ 30 | loading.value = true; 31 | 32 | })

ZheFrench
  • 1,164
  • 3
  • 22
  • 46
  • 1
    You're missing basics, it would be the same without DTO and any extra things. You're trying to access promise result synchronously, which isn't possible by the definition of promises. See https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call . Asynchronous code belongs to onMounted. You can write it conveniently with async/await but I'd suggest to not do this before figuring out how it works with raw promises and `then`. – Estus Flask Aug 05 '21 at 12:29
  • Yeah I'm beginner and I'd like to use this example to better understand the whole stuff. I changed using async onMounted function. The loading is passing to true so text is displayed but not v-list items. I don't understand why releases don't"t wait the return of the call to ReleaseApi to be then displayed in the view. Also I dont know how to initialise correcly the releases value and If I need the use of Promise.resolve somewhere. In the console releases display well the array with two object Release. Any help would be appreciate. :) – ZheFrench Aug 05 '21 at 13:39
  • 1
    It doesn't wait because you didn't make it wait. You physically can't wait for *asynchronous* operation in *synchronous* code. Consider checking the link above, it discusses fundamental things that are relevant to your case. You're misusing a ref, its purpose is to hold a reference to a value, hence the word. You already passed original `releases` to a view with `return`, it will be clueless of any other value you assign to it, it should be never reassigned, instead should be `releases.value = ...`. – Estus Flask Aug 05 '21 at 13:57
  • 1
    `Promise.resolve` converts non-promise to a promise. If you already have existing promise like here, you dont need it or `new Promise`. As for console, that's another common thing, see https://stackoverflow.com/questions/17546953/cant-access-object-property-even-though-it-shows-up-in-a-console-log – Estus Flask Aug 05 '21 at 13:57
  • Thanks for your comments. I changed again. It works. Still I don't know how should I declare releases in the setup(). So I use :any but that's not the best way to do it. And using let releases : Release[] | Promise = ref([]); give plenty of erros. (see update) – ZheFrench Aug 05 '21 at 14:54
  • 1
    `releases` is never a promise. It's not a value but a ref (an object with `value` key). It should be `const releases = ref([])`, const because it's never reassigned. – Estus Flask Aug 05 '21 at 15:05
  • Yep true ! Thanks a lot ! – ZheFrench Aug 05 '21 at 15:10

0 Answers0