Calling components may result in a race condition

I have integrated 2 components into my "App" that work together seamlessly. The first component is responsible for resolving the external IP address to a geographical location by making 2 axios.get calls and then passing them back to App.vue using emit.

Following this, I call upon "Weather" to retrieve the latitude/longitude data from the previous calls and fetch relevant weather information from the darksky API based on that location. However, I am encountering a race condition issue where sometimes, due to latency (about 50-60% of the time), I end up sending 0/0 coordinates to Weather, which are what I initialize as default values in App.vue. I am seeking ways to improve the reliability of the following code execution.

Here's the template structure in App.vue

<template>
  <div id="app">
        <img alt="Vue logo" src="./assets/logo.png">
    <ip @response="onResponse" /> // Requires completion before proceeding (includes axios calls)
    <Weather msg="The weather for:" :lat="lat" :long="long" :ip="ip" :city="city" :country="country"/>
  </div>
</template>

<script>
import Weather from './components/Weather.vue'
import ip from './components/ip_resolve.vue'

export default {
  name: 'App',
  data() {
    return {
      lat: 0,
      long: 0,
      ip: 0,
      country: 0,
      city: 0 
    }
  },
  components: {
    Weather,
    ip
  },

  //Listen for emitted values from ip_resolve - ensure data is updated before Weather runs
  methods: {
    onResponse(event) {
      this.lat = event.lat
      this.long = event.long
      this.ip = event.ip
      this.country = event.country
      this.city = event.city
    }
  }
}
</script>

ip_resolve.vue Component:

<template>
  <div class="Hemlo">

  </div>
</template>

<script>
const axios = require('axios').default;
const ipRegex = /ip=(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})$/gmi
export default {
  name: 'ip',
  props:{
      ip: String,
      country: String,
      City: String,
      lat: Number,
      long: Number
  },
  mounted () {
    axios.get('https://www.cloudflare.com/cdn-cgi/trace')
    .then(response => (
        this.ip = ipRegex.exec(response.data)[1]
    )
        .then(
            axios.get('https://cors-anywhere.herokuapp.com/http://api.ipstack.com/'+this.ip+'?access_key=<key>')
            .then( response => (
                    this.lat = response.data.latitude,
                    this.long = response.data.longitude,
                    this.country = response.data.country_name,
                    this.city = response.data.city
                ).then(
                    this.$emit('response', {
                        ip: this.ip,
                        lat: this.lat,
                        long: this.long,
                        country: this.country,
                        city: this.city
                    })
                )
            )
        )
    )
  }
}
</script>

Weather.vue Component:

<template>
  <div class="Hi">
    <h1>{{msg}} {{city}}, {{country}}</h1>
    <h2>Temp: {{ temp }}f</h2>
    <h2>Conditions: {{ conditions }}</h2>
  </div>
</template>

<script>

const axios = require('axios').default;
export default {
  name: 'Weather',
  props: {
    msg: String,
    resp: String,
    ip: String,
    lat: Number,
    long: Number,
    city: String,
    country: String,
    temp: String,
    conditions: String
  },
  mounted () {
    axios
      .get('https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/<key>/'+this.lat+','+this.long)
      .then(response => (
        this.resp = response.data,
        this.temp = response.data.currently.temperature,
        this.conditions = response.data.currently.summary
      ))
  }

}
</script>

Answer №1

To maintain a clean data flow for components, it is recommended to segregate model logic into its own module using tools like vuex.

However, if you're looking for a quick fix in this scenario, you can simply add a v-if="responseReady" directive to the <Weather> component in App.vue. This ensures that the component is only mounted once the necessary data is retrieved. Additionally, you will need to create a boolean flag for the new prop in the data and onResponse methods. While this solution may not be the most elegant, it gets the job done swiftly.

  <Weather v-if="responseReady"  msg="The weather for:" :lat="lat" :long="long" :ip="ip" :city="city" :country="country"/>
...
  data() {
    return {
        lat: 0,
        long: 0,
        ip: 0,
        country: 0,
        city: 0,
        responseReady: false
      }
    }, 
...
    onResponse(event) {
      this.lat = event.lat
      this.long = event.long
      this.ip = event.ip
      this.country = event.country
      this.city = event.city
      this.responseReady = true;
    }

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

Displaying nested JSON data in a user interface using React

I have a complex nested JSON structure that I am using to build a user interface. While I have successfully implemented the first part, I am encountering difficulties with the second part. My Objective The nested JSON displays parent elements and now I a ...

Using third-party libraries like jQuery, CSS, and JavaScript in your React project by directly importing them into the index.html file can be a more efficient approach compared

When working with React, is it advisable to import external JavaScript, jQuery, and CSS files into the index.html file in the public folder? Are there any potential performance implications associated with this practice? I have utilized some jQuery functi ...

Consistently obtaining the same outcome in JavaScript, always

Is it possible to resolve this issue? I keep getting a result of less than 18 when trying numbers 1-100, even though the output should be for values under 18. In my HTML code, there is a <p> element with id="result", an input with id=&quo ...

Steps to remove information from a database using PHP, AJAX, and vanilla JavaScript (without jQuery)

I am facing an issue with deleting data from my database. Whenever I click on the delete button, it deletes the first row instead of the intended row. Below is my PHP code: <?php $connect = mysqli_connect("localhost","root","","abu"); if($conne ...

How can I clear the div styling once the onDismiss handler has been triggered

Seeking assistance with resetting a div on a Modal after it has been closed. The issue I am facing with my pop-up is that the div retains the previous styling of display: none instead of reverting to display: flex. I have searched for a solution without su ...

Obtain the real-time inventory quantity of the specific product variation in WooCommerce

When a WooCommerce product variation's stock quantity is 0 or less and backorders are allowed, I want to offer customers the option to pre-order the item on the product page. To clearly indicate this to customers, the "Add to Cart" button should chan ...

Error: The function of Bootstrap toggle is not defined

Currently, I am working on a Django application for warehouses and stockists. My goal is to create a list of stockists per warehouse in a button list format. When this button is clicked, a modal window should appear displaying the name, position, and permi ...

Steps for automatically retrying a failed expect statement in Jest

In my React application, I am utilizing Jest for performing unit testing. One aspect of my application involves a Material UI date picker with next and previous buttons. The selected date is displayed in the browser URL. Each time the user clicks on the ne ...

Is it possible to obtain a user's public URL using the Facebook API in version 2?

In version 1, it is possible to obtain the user's public link by using the following endpoint: /v1.0/me function testAPI() { console.log('Welcome! Fetching your information....'); FB.api('/me', function(response) { ...

getStaticProps only runs on IIS after the entire page is refreshed

Using the nextjs getStaticProps feature in my project has been smooth sailing so far. However, after uploading the Static files to IIS, the feature seemed to stop working until I configured a urlRewrite module on it. I noticed that when initially visiting ...

"Guide to terminating an AWS Batch job that is in a RUNNABLE state using the JavaScript SDK

I need assistance with canceling a job stuck in runnable status on AWS Batch using the JavaScript SDK. Which API option should I choose? 1. The TerminateJobCommand documentation states that it terminates jobs in the STARTING or RUNNING state, causing them ...

Resize a div within another div using overflow scroll and centering techniques

Currently, I am working on implementing a small feature but am facing difficulties with the scroll functionality. My goal is to zoom in on a specific div by scaling it using CSS: transform: scale(X,Y) The issue I am encountering lies in determining the c ...

Pagination does not refresh when conducting a search

HTML Code: The following HTML code displays a table with a search filter. . . <input type="search" ng-model="search.$" /> <table class="table table-striped table-bordered"> <thead> <tr> <th><a href ...

the div background is limited to the exact size of the text, not filling the entire

Currently, as I work on my web page using react.js, I'm facing the challenge of implementing a full-size background. Despite my efforts, the background only occupies the size of the text within the div. Here is the snippet of code I am working with: a ...

Using a regular div to display a modal - Reactstrap

Exploring the possibilities with a Reactstrap Modal: Modal - Reactstrap I am curious about integrating this modal seamlessly into a page layout, similar to a regular div. For example, having the modal display on the page without the animation effects and ...

Implementing JavaScript to display specific content when a list is devoid of any items

Currently, I am in the process of developing a basic contact list web application where the contacts are listed within li elements. My aim is to adjust the visibility of the text in the p#no-contacts element based on whether the containing ul has any child ...

Various outcomes were calculated for multiple Vue.js inputs

I am facing an issue with multiple dynamically added search forms on my webpage. Currently, when a user performs a search on one form, all inputs are being searched instead of just the relevant one. Below is the HTML Code for reference: <div class="ro ...

What could be the reason for the malfunctioning transition effect in my slider animation?

Having trouble getting my slider animation to work. I've tried different CSS styles but the slide transition is not functioning as expected. When one of the buttons is clicked, I want the slide to change from right to left or left to right. Can anyone ...

Can a cross-browser extension be developed that integrates with a Python backend for a web application?

Present State I am currently in the initial stages of planning a web application that users will access through a browser extension designed as a horizontal navigation bar. My initial plan was to utilize Pylons and Python for this project, but I am uncert ...

Troubleshooting Vue.js 2 Routing Issues: Difficulty Accessing Posts Variable

My first venture into Vue.js involves working with WP REST API. Initially, all my posts are displayed perfectly. However, when I attempt to integrate Vue-router, the component responsible for showcasing all the posts, 'home-post-list', breaks do ...