Search code examples
vue.jsvue-componentvue-composition-api

How to fetch results returned from a web-service


i am learning how to call a web-service and how to use event-emitters. i developed the below posted example, where GISWSCaller is a child component the should invoke the web-service via the designated url, and where App is the parent component. at run time, i receive the following errors:

1.  Uncaught (in promise) TypeError: fetch(...).json is not a function that 
stemmed from the following code:

res.value = await fetch('https://x.xx/xxx/getDistanceFromOriginToDestination/30.976639,30.056021,30.97775,30.033333').json()

2. `defineEmits` are referencing locally declared variables which stemmed 
from the following code:

const res = ref(null)
const emit = defineEmits({
evtRunWSRouteTest:async (params) => {
    const splitted = params.split(',')
    if (splitted.length == 4) {
        res.value = await fetch('https://xx.xxx/xx/getDistanceFromOriginToDestination/30.976639,30.056021,30.97775,30.033333').json()
        return res.value
    }
    return false
}

})

please let me know how to fix the priviously stated errors

GISWSCaller:

<template>
  <div class="container">
    <button @click="originDestLonLat('30.976639,30.056021,30.97775,30.033333')">routTest</button>
    result:{{ res }}
  </div>
</template>

<script>
import { defineEmits, ref,onMounted } from 'vue';
export default {
  name: 'GISWSCaller',
}
</script>

<script setup>
const res = ref(null)
const emit = defineEmits({
evtRunWSRouteTest:async (params) => {
    const splitted = params.split(',')
    if (splitted.length == 4) {
        res.value = await fetch('https://xx.xx/xxx/getDistanceFromOriginToDestination/30.976639,30.056021,30.97775,30.033333').json()
        return res.value
    }
    return false
}

})

// functions
function originDestLonLat(params) {
    console.log("params:",params);
    emit('evtRunWSRouteTest',params)
}
</script>

App:

<template>
  <g-i-s-w-s-caller @evtRunWSRouteTest="evtReceiverForRunWSRouteTest"/>
</template>

<script>
import GISWSCaller from './components/GISWSCaller.vue'
import { reactive} from 'vue'

export default {
  name: 'App',
  components: {
    GISWSCaller
  }
}
</script>

<script setup>

function evtReceiverForRunWSRouteTest(e) {
  console.log("evt:",e);
}
</script>

update:

the following code returns:

Uncaught (in promise) SyntaxError: Unexpected token 'D', "Distance: "... is not valid JSON

const emit = defineEmits({
evtRunWSRouteTest:async (params) => {
    const splitted = params.split(',')
    if (splitted.length == 4) {
        const response = (await fetch('https://xx.xx-x/xx/getDistanceFromOriginToDestination/30.976639,30.056021,30.97775,30.033333')) //<==change occured here
        res.value = response.json() //<==change occured here
        return res.value
    }
    return false
}
})

screen-shot:

enter image description here

web-service:

@app.route("/getDistanceFromOriginToDestination/<string:originAndDestinationGPSCoords>", methods=['GET'] )
def getDistanceFromOriginToDestination(originAndDestinationGPSCoords):

global gpsCoordinates
gpsCoordinates = originAndDestinationGPSCoords
isCohesiveData = CoordinatesUtils.isInputCoordinatesCohesive(gpsCoordinates)
if (isCohesiveData):
    logging.info("data is cohesive")
    data = FlaskAccessControlUtils.fetchDataForURL(OpenRouteServiceUtils.getBaseURL(gpsCoordinates))
    distance = OpenRouteServiceUtils.getDistanceAsJSON(data)
else:
    print("data is not cohesive")
    abort(400, 'Record not found')

res = {
    "dist":'Distance: %f km '%(MiscUtils.getDistanceFromOriginToDestinatioInKilometers(float(distance)))
}

return jsonify(res)

Solution

  • fetch() returns a Promise which resolves to a Response.

    json() is a method that is found on the Response, not on the Promise.

    You need to await the resolved value of fetch() and then call json() on that value.