Vue.js: Retrieving and Using Data from the API Repeatedly

<template>
    <h1 class="text-lg text-gray-400 font-medium">Tracker dashboard</h1>
    <div class="flex flex-col mt-2 w-3/4">
        <div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
            <div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
                <div class="shadow overflow-hidden sm:rounded-lg">
                    <table class="min-w-full text-sm text-gray-400">
                        <thead class="bg-gray-800 text-xs uppercase font-medium">
                            <tr>
                                <th></th>
                                <th scope="col" class="px-6 py-3 text-left tracking-wider">
                                    Coin
                                </th>
                                <th scope="col" class="px-6 py-3 text-left tracking-wider">
                                    Price
                                </th>
                                <th scope="col" class="px-6 py-3 text-left tracking-wider">
                                    24h
                                </th>
                                <th scope="col" class="px-6 py-3 text-left tracking-wider">
                                    7d
                                </th>
                                <th scope="col" class="px-6 py-3 text-left tracking-wider">
                                    30d
                                </th>
                                <th scope="col" class="px-6 py-3 text-left tracking-wider">
                                    market cap
                                </th>
                            </tr>
                        </thead>
                        <tbody v-for="(item, index) in list.coinsList" class="bg-gray-800">
                            <tr class="bg-black bg-opacity-20">
                                <td class="pl-4">
                                    {{ index + 1}}
                                </td>
                                <td class="flex px-6 py-4 whitespace-nowrap">
                                    <img class="w-5" :src="images[index]">
                                    <span class="ml-2 font-medium">{{coins[index]}}</span>
                                </td>
                                <td class="px-6 py-4 whitespace-nowrap">
                                     ${{ item.current_price.usd }}
                                </td>
                                <td class="px-6 py-4 whitespace-nowrap">
                                    {{ item.price_change_percentage_24h }}%
                                </td>
                                <td class="px-6 py-4 whitespace-nowrap">
                                    {{ item.price_change_percentage_7d }}%
                                </td>
                                <td class="px-6 py-4 whitespace-nowrap">
                                    {{ item.price_change_percentage_30d }}
                                </td>
                                <td class="px-6 py-4 whitespace-nowrap">
                                    ${{ item.market_cap.usd }}
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</template>


<script setup>
import { reactive } from 'vue'
import { api } from '../services/api'
import bitcoinImg from "../assets/bitcoin.png"
import dacxiImg from "../assets/dacxi.png"
import ethImg from "../assets/ethereum.png"
import atomImg from "../assets/atom.png"
import lunaImg from "../assets/luna.png"

const coins = ['bitcoin', 'dacxi', 'ethereum', 'cosmos', 'terra-luna-2']
const images = [bitcoinImg, dacxiImg, ethImg, atomImg, lunaImg]
const list = reactive({
    coinsList: [],
});

coins.forEach((item) => {
    api.get(`/coins/${item}`)
    .then((response) => {
        list.coinsList.push(response.data.market_data)
    })
})

</script>

Hi everyone, I'm exploring Vue and encountering a challenge with this code. I'm looking for a more efficient approach. I attempted using onMounted but didn't achieve the desired outcome. How can I prevent the list from displaying out of order at times? Additionally, what steps can I take to incorporate the name and images into the JSON to avoid displaying them in the incorrect order?

View Example Rendered

Answer №1

One way to achieve this is by implementing the following solution:

const cryptoCurrencies = [
 {
   name: 'Bitcoin',
   image: bitcoinLogo,
   data: []
 },
 {
   name: 'Ethereum',
   image: ethereumLogo,
   data: []
 },
etc...
]

cryptoCurrencies.forEach(crypto => {
  api.get(`/crypto/${crypto.name}`)
    .then((response) => {
        crypto.data.push(response.data.market_info)
    })
}

Answer №2

Promise.all(
    currencies.map((item, index) =>
        api
        .get(`/currencies/${item}`)
        .then((response) => ({ 
          ...response.data.market_data, 
          _currency: item, // include _currency - which corresponds to currencies[index]
          _logo: logos[index]  // include _logo - which corresponds to logos[index]
        }))
    )
).then((d) => (list.currenciesList = d));

slight modifications to HTML as observed

<tbody v-for="(item, index) in list.currenciesList" class="bg-gray-800">
  <tr class="bg-black bg-opacity-20">
    <td class="pl-4">
      {{ index + 1}}
    </td>
    <td class="flex px-6 py-4 whitespace-nowrap">
      <img class="w-5" :src="item._logo"> <!-- modified -->
      <span class="ml-2 font-medium">{{item._currency}}</span> <!-- modified -->
    </td>
    <td class="px-6 py-4 whitespace-nowrap">
      ${{ item.current_value.usd }}
    </td>
    <td class="px-6 py-4 whitespace-nowrap">
      {{ item.value_change_percentage_24h }}%
    </td>
    <td class="px-6 py-4 whitespace-nowrap">
      {{ item.value_change_percentage_7d }}%
    </td>
    <td class="px-6 py-4 whitespace-nowrap">
      {{ item.value_change_percentage_30d }}
    </td>
    <td class="px-6 py-4 whitespace-nowrap">
      ${{ item.market_value.usd }}
    </td>
  </tr>
</tbody>

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

Creating a Related Entry in strapi v4: A Step-by-Step Guide

Whenever I try to add a new record in my Collection-Type, all the field values are successfully added to the new entry except for the value in the field with a Relation type. For instance, in my event Collection-Type, I have fields like name, performers, ...

The object displays a value when inspected in the console, but appears as null when checked in the controller (Laravel)

In my form object, I have the following fields: { form: { a: '', b: '', c: '', d: '', e: '', f: '', g: '' } } When I chec ...

Leveraging the power of nodejs functions within static HTML files in expressJs

Being a beginner in Javascript and Nodejs, I am uncertain about the best way to organize my project. I am currently working on creating a web interface for a C++ application using Nodejs and V8 to wrap a C++ API. My question is, can I utilize Express to se ...

The Ionic AngularJS http service is failing to update the controller

I'm struggling to understand why my controller is receiving an empty array after calling the service, which triggers an http call. Here's how I have set up my app: Here is my app.js file: //App.js .state('myApp.sermonlists', { u ...

The nested promise.all function is executing synchronously instead of asynchronously as anticipated

Within the nested Promise.all section of my NodeJs script, I believe there is an error. The script is designed to process multiple .csv files within a directory, creating a database record for each row. If a row fails processing, it is added to a list of f ...

Having trouble animating a collapse element in Bootstrap 5 that was dynamically created using JavaScript

My objective is to develop a collapsible element that notifies the user about the success or error of sending form data to the server. This will provide clear feedback to the user after form submission. function sendForm(event, form) { const notif ...

Structuring React components - Incorporating a form within a modal

I am currently utilizing the react-bootstrap Modal, Form, and Button components. My goal is to have the button trigger the modal window containing a form. Once the form is filled out, clicking another button within the modal will validate the data and sen ...

I am looking to display data for all the months of the year using Vue.js and Laravel on the backend

I am working with Laravel on the backend and Vue.js on the frontend. Currently, I am developing an API to retrieve all data without any filtering based on month. My question is: how can I display data for each specific month in a Vue.js template? For in ...

Troubleshooting Vue component reactivity problems with async server requests

Providing some background information: Within my Vue application, I have a view called Articles. Upon mounting this component to the DOM, I use the axios library to fetch all posts from the database through Laravel controllers and API routes. In the articl ...

Adding and deleting MPEG-DASH segments from a media source buffer in a dynamic manner

I have been developing a custom MPEG-DASH streaming player using the HTML5 video element. Essentially, I am setting up a MediaSource and attaching a SourceBuffer to it. After that, I am appending DASH fragments into this sourcebuffer and everything is func ...

Invoking a Method in a React Component from its Parent Component

I am new to React and I have a question regarding how to call a method from a child component within the parent component. For example: var ChildClass = class Child { howDoICallThis () { console.log('Called!') } render () { retur ...

Reducing the slide margins in impress.js?

When using Impress.js, I noticed that the default slides have a large left margin (or padding - it's hard to determine with Firefox's Inspector). I have a slide with a wide <pre> block that would fit if it were aligned to the left, but it d ...

Utilize JavaScript or Jquery programming to restrict the entry of special characters from the numeric keypad

For the project I'm working on, I need to block users from entering specific characters in a text box: !@#$%^&*(). Can anyone advise me on how to accomplish this using JavaScript/jQuery? The application is built with ASP.NET. ...

What is the best way to define one API route that accommodates two different query combinations?

Is it possible to define 1 API route with 2 different query combination options? We have 2 routes: GET /api/v1/resource?filter=byName&key=restaurant&city=chicago GET /api/v1/resource?filter=byLocation&lat=34&long=78 In soaJS, schema ...

Using a variety of objects in TypeScript arrays

How to effectively implement a superior class in TypeScript for an array containing diverse objects that inherit from the same class, without triggering errors? This is my attempt: interface IVehicle{ modelName: string } interface ICar extends IVehi ...

Tips on passing a variable into a controller using jQuery AJAX from the URL

Can you help me figure out how to pass an id to a function in the controller? I keep getting an error saying it cannot find the method in the controller. Here's my view: function Delete1(id) { if (confirm("Are you sure?")) { $. ...

When it comes to AFrame+Three.js, which is more efficient: having numerous meshes with minimal triangles per mesh or having a few meshes with a high number of

Currently working with Aframe 1.0.4 and Three.js 111, I am exploring the performance differences between: Whether it is better to have a few entities with a high number of triangles or many entities with fewer triangles each. Specifically, I am debating ...

Transferring information within React components

Looking for some assistance with the code below. I'm facing an issue where the data is not being submitted along with the form, even though the correct values are displayed in the form. I have included a user query to fetch data from another object an ...

Tips for inserting a Vue.js variable into a window.open event

Within this snippet of code: <tr v-for="person, index in People" :key='index'> <td> <button type="button" onclick="window.open('/details/'+person.id,'_blank')"> details</butto ...

Displaying subsets of data based on the identifier of the primary array

In my JSON file, I have an array containing various categories and their respective subcategories. { "Women": [ { "id" : 1, "name" : "See All", &q ...