Problem with CORS. Google directions API GET request | vue.js - google-maps-api-3

I currently work on vue.js project.
The app goal is to check distance between 2 localisations, then show route on the map and calculate cost of transport which is based on the distance.
I use google directions api, axios for get request.
Problem is that, because of CORS, get request gives me an error (I run this app locally).
I already tried chrome CORS plugin, but problem still exists.
Do You have any solutions or just idea how to solve this problem?
Thank You in advance.
P.S.
Code below
import axios from 'axios';
const directionsApi = 'https://maps.googleapis.com/maps/api/directions/json?';
const apiKey = '&key=trust_me_the_key_is_valid';
export default {
name: 'FirstForm',
data() {
return {
fromValue: '',
toValue: '',
distance: '',
};
},
methods: {
handleFromToInput: function () {
const fromTo = `origin=${this.fromValue}&destination=${this.toValue}`;
axios.get(`${directionsApi}${fromTo}${apiKey}`)
.then((response) => {
// this.distance = response.routes[0].legs[0].distance.text;
console.log(response.routes[0].legs[0].distance.text);
})
.catch((error) => {
console.log(error);
});
},
},
};

Similar here
If you use Javascript API way to do,
Create an account on Google Maps Platform
Open Vue Project
Make a js file (src/utils/gmap.js)
// src/utils/gmaps.js
const API_KEY = 'XXXXXYOURAPIKEYXXXX';
const CALLBACK_NAME = 'gmapsCallback';
let initialized = !!window.google;
let resolveInitPromise;
let rejectInitPromise;
const initPromise = new Promise((resolve, reject) => {
resolveInitPromise = resolve;
rejectInitPromise = reject;
});
export default function init() {
if (initialized) return initPromise;
initialized = true;
window[CALLBACK_NAME] = () => resolveInitPromise(window.google);
const script = document.createElement('script');
script.async = true;
script.defer = true;
script.src = `https://maps.googleapis.com/maps/api/js?key=${API_KEY}&callback=${CALLBACK_NAME}`;
script.onerror = rejectInitPromise;
document.querySelector('head').appendChild(script);
return initPromise;
}
In view js (src/views/MyMap.vue)
<template>
<div class="my-map">
My Map
<div id="map"></div>
</div>
</template>
<script>
import gmapsInit from '#/utils/gmaps';
export default {
name: 'myMap',
components: {
},
data () {
return {
}
},
computed: {
},
async mounted() {
try {
const google = await gmapsInit();
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
} catch (error) {
console.error(error);
}
},
methods:{
}
}
</script>
<style>
#map{
width:400px;
height:400px;
}
</style>
Ref on
Using the Google Maps API with Vue.js
Maps JavaScript API, Hello World

I've found solution. Maybe it's not best but it works.
I've used cors-anywhere proxy.
https://cors-anywhere.herokuapp.com/${directionsApi}${fromTo}${apiKey}

Related

Unable to listen for event on received DASH transaction using MeteorJS and DASH npm package

I am using the DASH npm package with a MeteorJS application. I would like to be able to listen for transaction events so I can call a Meteor method called "funds" whenever a transaction is sent to my wallet. However, I am receiving "undefined" errors in the console when attempting to set this up.
Documentation:
https://dashevo.github.io/platform/SDK/examples/receive-money-and-check-balance/
https://www.npmjs.com/package/dash
What I would like to do looks in theory like this (fixtures.js):
import { Meteor } from 'meteor/meteor';
Meteor.startup(() => {
const Dash = require("dash");
const mnemonic = 'there ghost stay ripple silk gym curtain body salad icon sentence service';
const client = new Dash.Client({ network: "testnet", wallet: { mnemonic } });
client.getWalletAccount().then(async (account) => {
account.events.on('FETCHED_CONFIRMED_TRANSACTION', (data)=>{
var amount = data.amount;
var address = data.address;
if (address) {
Meteor.call('funds', address, amount, (error) => {
if (error) {
console.log(error);
}
});
}
});
});
});
This is what I have and what has worked successfully:
import { Meteor } from 'meteor/meteor';
Meteor.startup(() => {
const Dash = require("dash");
const mnemonic = 'there ghost stay ripple silk gym curtain body salad icon sentence service';
const client = new Dash.Client({ network: "testnet", wallet: { mnemonic } });
client.getWalletAccount().then(async (account) => {
console.log("Funding address", account.getUnusedAddress().address); // THIS WORKS!!!
console.log("Confirmed Balance", account.getConfirmedBalance()); // THIS WORKS!!!
// THE FOLLOWING DOES NOT CURRENTLY WORK!!!
// account.events.on('FETCHED_CONFIRMED_TRANSACTION', (data)=>{
// console.log('FETCHED/UNCONFIRMED_TRANSACTION');
// console.dir(data);
// var amount = data.amount;
// var address = data.address;
// if (address) {
// Meteor.call('funds', address, amount, (error) => {
// if (error) {
// console.log(error);
// }
// });
// }
// });
});
});
I have also tried the following per the documentation to no avail:
import { Meteor } from 'meteor/meteor';
Meteor.startup(() => {
const Dash = require("dash");
const mnemonic = 'there ghost stay ripple silk gym curtain body salad icon sentence service';
const client = new Dash.Client({ network: "testnet", wallet: { mnemonic } });
client.account.events.on('FETCHED/UNCONFIRMED_TRANSACTION', (data)=>{
console.log('FETCHED/UNCONFIRMED_TRANSACTION');
console.dir(data)
});
});
Thank you for your help
the documentation is currently in the process of updating
Instead of account.events.on do account.on
https://github.com/dashevo/platform/issues/377#issuecomment-1124617321

Composition API - Axios request in setup()

I am experimenting with Vue3's Composition API in a Laravel/VueJS/InertiaJS stack.
A practice that I have used a lot in Vue2 with this stack is to have 1 route that returns the Vue page component (eg. Invoices.vue) and then in the created() callback, I would trigger an axios call to an additional endpoint to fetch the actual data.
I am now trying to replicate a similar approach in Vue3 with composition API like so
export default {
components: {Loader, PageBase},
props: {
fetch_url: {
required: true,
type: String,
}
},
setup(props) {
const loading = ref(false)
const state = reactive({
invoices: getInvoices(),
selectedInvoices: [],
});
async function getInvoices() {
loading.value = true;
return await axios.get(props.fetch_url).then(response => {
return response.data.data;
}).finally(() => {
loading.value = false;
})
}
function handleSelectionChange(selection) {
state.selectedInvoices = selection;
}
return {
loading,
state,
handleSelectionChange,
}
}
}
This however keeps on giving me the propise, rather than the actual data that is returned.
Changing it like so does work:
export default {
components: {Loader, PageBase},
props: {
fetch_url: {
required: true,
type: String,
}
},
setup(props) {
const loading = ref(false)
const state = reactive({
invoices: [],
selectedInvoices: [],
});
axios.get(props.fetch_url).then(response => {
state.invoices = response.data.data;
}).finally(() => {
loading.value = false;
})
function handleSelectionChange(selection) {
state.selectedInvoices = selection;
}
return {
loading,
state,
handleSelectionChange,
}
}
}
I want to use function though, so I can re-use it for filtering etc.
Very curious to read how others are doing this.
I have been googling about it a bit, but cant seem to find relevant docu.
All feedback is highly welcomed.
I tried this now with async setup() and await getInvoices() and <Suspense> but it never displayed any content.
So this is how I'd do it, except I wouldn't and I'd use vuex and vuex-orm to store the invoices and fetch the state from the store.
<template>
<div>loading:{{ loading }}</div>
<div>state:{{ state }}</div>
</template>
<script>
import {defineComponent, ref, reactive} from "vue";
import axios from "axios";
export default defineComponent({
name: 'HelloWorld',
props: {
fetch_url: {
required: true,
type: String,
}
},
setup(props) {
const loading = ref(false)
const state = reactive({
invoices: []
})
async function getInvoices() {
loading.value = true;
await axios.get(props.fetch_url).then(response => {
state.invoices = response.data;
}).finally(() => {
loading.value = false;
})
}
return {
getInvoices,
loading,
state,
}
},
async created() {
await this.getInvoices()
}
})
</script>
<style scoped>
</style>
This is of course similar to what you're doing in option 2.

How to test router code that contains heavy logic using sinon and stubbing (nodeJS)

I am new to using sinon, so sorry if my question is weird, I looked everywhere but can't find a way to do it.
I have app with express router. I want to write uint test for one of the routes. That route have an inner function that is 'heavy', meaning that it is async with promise, and in reality calls an external api. I want to stub that inner function in the test so that it will not use the api, and will return my own data instead of the original method.
This is the code so far:
routes/setOrder.js:
// the inner function I want to stub
var verifyPayment = function(saleId) {
return new Promise((resolve, reject) => {
logger.info(`verifyPayment: ${saleId}`);
externalAPICall.get( // <==this is the 'heavey part!!
saleId,
function (error, sale) {
if(error) {
return reject(`Error querying sale(${saleId}): ${error}`);
}
resolve(sale);
});
});
}
router.get('/paymentId/:paymentId', setOrderWithGet);
const setOrderWithGet =async function(req, res, next) {
const { paymentId } = req.params;
verifyPayment(paymentId)
.then(async sale => {
try {
console.log(`sale:${sale}`);
res.send(JSON.stringify({"status": "ok!" }));
} catch (err) {
logger.warn(err)
res.send(JSON.stringify({"status": "fail.."}));
}
})
.catch(reason => {
logger.warn(`[] Payment(${paymentId}) is not valid ${reason}`);
res.send(JSON.stringify({"status": "fail.."}));
});
}
module.exports = router;
module.exports.setOrderWithGet = setOrderWithGet;
module.exports.verifyPayment = verifyPayment;
setOrderTest.js:
const setOrderStub = require('../routes/setOrder');
describe("POST /setOrder", () => {
beforeEach(() => {
sinon.stub(setOrderStub, 'verifyPayment').resolves({....});
});
afterEach(() => {
sinon.restore();
});
describe("test1", () => {
it("setOrder first attempt", () => {
let req ={params : {'paymentId' : 'mypamentid1'}};
setOrderStub.setOrderWithGet(req,{});
});
});
});
This line:
sinon.stub(setOrderStub, 'verifyPayment').resolves({....});
...stubs the verifyPayment function on the module exports of the setOrder module.
Right now setOrderWithGet is calling the verifyPayment function directly, so it is unaffected by any changes to the module exports.
Change setOrderWithGet to call verifyPayment using the module exports:
const setOrderWithGet = async function(req, res, next) {
// ...
module.exports.verifyPayment(paymentId) // <= call the module export for verifyPayment
// ...
}
...and your stub will get called.

Using Pa11y with Supertest

What is the best way to use Pa11y with Supertest? Something like:
describe ('my page', function () {
it ('is accessible', function () {
request (server).get ('/').expect (function ({ body }) {
// How to run Pa11y here?
});
});
})
I would suggest not using supertest at all for these accessibility test as pa11y can ping url's directly.
const pa11y = require('pa11y');
const request = require('supertest');
const mocha = require('mocha');
const { expect } = require('chai');
const server = require('./server');
const url =
process.env.NODE_ENV === 'testing'
? 'http://localhost:3000'
: 'http://example.com';
describe('my page', function() {
it('is accessible', function(done) {
pa11y(`${url}/`, function(err, results) {
expect(results.issues).to.be.empty;
done();
});
});
});

Redux Chain Multiple Ajax Promises in one Action

I have a Redux action which needs to make 2 subsequent ajax calls.
The first calls googlemaps api: https://maps.googleapis.com/maps/api/geocode/json?address=${searchTerm}&key=${gmapsKey}
The second calls a local service based on those results
/api/content/stores/byDistance/${lat},${lng}/sort
I'm using superagent to do the ajax calls. Clearly I'm experience difficulties keeping track of the promises, and including failures.
Am I mis-undestanding a core concept of Promises? Is there a simpler way to write the below?
export function loadBySearch(searchTerm) {
const geoSearchUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${searchTerm}&key=${gmapsKey}`;
return {
types: [LOAD, LOAD_BY_LAT_LONG, LOAD_FAIL],
//Do I need to make this promise here?
promise: (client) => {
const promise = new Promise( (resolve, reject) => {
console.info('making google geocode request', geoSearchUrl);
superagent.get(geoSearchUrl)
.set('Accept', 'application/json')
.then( (successData1) =>{
const results = successData1.body.results;
if (!results.length) {
reject(`no results found for this search : ${searchTerm}`);
return;
}
const lat = results[0].geometry.location.lat;
const lng = results[0].geometry.location.lng;
const path = `/api/content/stores/byDistance/${lat},${lng}/sort`;
client.get(path).then(
(successData2) => {
resolve( {
searchTerm: searchTerm,
searchLocation: {
lat,
lng
},
data: successData2
});
},
(errorData2) => {
reject( {
searchTerm: searchTerm,
result: errorData2
});
},
);
},
(errorData1) => {
reject({
searchTerm: searchTerm,
result: errorData1
});
}
);
});
return promise;
}
};
}
I'm not using superagent, but I'm guessing something like this might just work:
superagent.get(geoSearchUrl)
.set('Accept', 'application/json')
.then(successData1 => {
const results = successData1.body.results;
if (!results.length) {
throw(`no results found for this search : ${searchTerm}`);
}
return Promise.resolve(results);
})
.then(results => {
const lat = results[0].geometry.location.lat;
const lng = results[0].geometry.location.lng;
const path = `/api/content/stores/byDistance/${lat},${lng}/sort`;
return client.get(path);
})
.then(successData2 => {
return Promise.resolve({
searchTerm: searchTerm,
searchLocation: {
lat,
lng
},
data: successData2
});
})
.catch(error => {
return Promise.reject({
searchTerm: searchTerm,
result: error
});
});
Haven't test it, but I hope at least it helps ;)

Resources