0

I created this function to calculated distances I want to measure:

distanceToResponder: function() {
    var distance = 0;
    var incidentLocation = this.createCoordinate(this.currentIncident["latitude"], this.currentIncident["longitude"]);

    this.responders.forEach(function(responder) {
        var responderLocation = this.createCoordinate(responder.location.latitude, responder.location.longitude);
        distance = this.calculateDistanceBetweenLocations(incidentLocation, responderLocation);
    }.bind(this));
    return distance;
}

for some reason which I do not see, the value for distance is only returned once. So if I throw 2 locations into the forEach function, and I use console.log within the loop, I see everything is calculated correctly. But if I return the value for distance, only one value is returned.

How do I return the value correctly?

I am using VueJS where 'distanceToResponder' is a computed property to fill a table:

   <tr v-for="responder in responders">
        <td>{{ responder.userReference }}</td>
        <td>{{ distanceToResponder(responder) }}</td>
        <td><button type="button" class="btn btn-danger" @click="createDispatch(responder)">Alarm</button></td>
    </tr>

so the function should return the distance for each responder. How do I need to adjust my function then?

2
  • You are returning the last calculated distance, and you can return from a function just once, anyway. You may be interested in the Array.map method Commented May 18, 2016 at 18:55
  • Well, a function can only return a single value. return distance; will return whatever the value of distance is at that moment. All you are doing is overwriting the value inside forEach. Commented May 18, 2016 at 19:12

4 Answers 4

2

You're not using return values at all here, except out of the outer most function call. Your inner forEach callback just sets the state of a single variable (distance) shared across both functions, which is eventually returned.

Each iteration of forEach overwrites the previous value of distance so that only the final value is left.

It's unclear what you mean by "return multiple" as a function may return only one value, but you can return an array of distances by using map instead of forEach:

distanceToResponder: function() {
    var incidentLocation = this.createCoordinate(this.currentIncident["latitude"], this.currentIncident["longitude"]);

    return this.responders.map(function(responder) {
        var responderLocation = this.createCoordinate(responder.location.latitude, responder.location.longitude);
        return this.calculateDistanceBetweenLocations(incidentLocation, responderLocation);
    }.bind(this));

}
Sign up to request clarification or add additional context in comments.

1 Comment

I edited my question accordingly. Actually I have an array of responders. with VueJS I go through this variable and want to calculate the distance to each individual responder via this function.
1

You are iterating your responders and each time overwrite distance. Then after iteration returning the distance to the last responder.

    var distances = this.responders.map(function(responder) {
      var responderLocation = this.createCoordinate(responder.location.latitude, responder.location.longitude);
      return this.calculateDistanceBetweenLocations(incidentLocation, responderLocation);
    }.bind(this));
    return distances;

Make a computed property "distancesToResponders" from this. And in the template

 <tr v-for="(index, responder) in responders">
    <td>{{ responder.userReference }}</td>
    <td>{{ distancesToResponder[index] }}</td>
    <td><button type="button" class="btn btn-danger" @click="createDispatch(responder)">Alarm</button></td>
</tr>

Or create a "augmented" responders computed property:

 respondersWithDistance: function() {

  var incidentLocation = this.createCoordinate(this.currentIncident["latitude"], this.currentIncident["longitude"]);

  return this.responders.map(function(responder) {
    var responderLocation = this.createCoordinate(responder.location.latitude, responder.location.longitude);
    responder.distance = this.calculateDistanceBetweenLocations(incidentLocation, responderLocation);
 }.bind(this));
}

And use that also in the template:

 <tr v-for="responder in respondersWithDistance">
    <td>{{ responder.userReference }}</td>
    <td>{{ responder.distance }}</td>
    <td><button type="button" class="btn btn-danger" @click="createDispatch(responder)">Alarm</button></td>
</tr>

2 Comments

I want to do the first. but instead of returning an array of distances, I want to fill a table with the individual distances (adjusted questions above) via VueJS
What would be the "cleaner" or more common way?
1

I'm going to assume you want to return an array of distances, one for each responder. As it is, you're overwriting the distance variable each time, and only returning its final value. I recommend using map() instead of forEach() to return all the values as an array:

distanceToResponder: function() {
    var incidentLocation = this.createCoordinate(this.currentIncident["latitude"], this.currentIncident["longitude"]);

    return this.responders.map(function(responder) {
        var responderLocation = this.createCoordinate(responder.location.latitude, responder.location.longitude);
        return this.calculateDistanceBetweenLocations(incidentLocation, responderLocation);
    }.bind(this));
}

Comments

0

The respective responder must be passed as argument. The iteration is done by vue.

distanceToResponder: function(responder) {
  var distance = 0;
  var incidentLocation = this.createCoordinate(this.currentIncident["latitude"], this.currentIncident["longitude"]);

  var responderLocation = this.createCoordinate(responder.location.latitude, responder.location.longitude);
  return this.calculateDistanceBetweenLocations(incidentLocation, responderLocation);
}

1 Comment

I was hoping this would work, but distanceToResponder is a computed property and I guess this cannot take an argument? or am I wrong

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.