Geocoding API and Geocoder Class - different result for same address - geocoding

So, sounds like this question was asked before, but actually this one is different.
The problem is that Geocoding API is modifying the given address.
address = '750,West Broadway,Vancouver,V5Z 1H2,British Columbia,Canada';
https://maps.googleapis.com/maps/api/geocode/json?address=address&key=API_KEY
1.
Response from Geocoding Static API url:
{
formatted_address: '750 W Broadway, Vancouver, BC V5Z 1J4, Canada',
place_id: 'ChIJ_RRP_8NzhlQRVS9i9yqSAKY'
}
2.
Response from Geocoder Class with the same address:
{
formatted_address: '750 W Broadway, Vancouver, BC V5Z 1H2, Canada',
place_id: 'ChIJxQEI2cJzhlQRf44wwGpQBNQ'
}
Different place_id and Post Code.
This creates a problem when using the place id with other services like Directions, StreetView.
const getGoogleMapAndStreetView = async (placeId) => {
const geocoder = new map.Geocoder();
const streetViewService = new map.StreetViewService();
const directionsService = new map.DirectionsService();
const geoResult = await geocoder.geocode(
{
placeId: placeId,
},
(geoResult, status) => {
if (status === "OK") {
return geoResult;
}
}
);
const origin = { placeId: geoResult.results[0].place_id };
const directionsResult = await directionsService.route(
{
origin: origin,
destination: origin,
travelMode: map.TravelMode.DRIVING,
},
(directionsResult, status) => {
if (status === "OK") {
return directionsResult;
}
}
);
const panoResult = await streetViewService.getPanorama(
{
location: directionsResult.routes[0].legs[0].start_location,
source: map.StreetViewSource.OUTDOOR,
radius: 50,
},
(panoResult, status) => {
if (status === "OK") {
return panoResult;
}
}
);
const newHeading = map.geometry.spherical.computeHeading(
new map.LatLng(panoResult.data.location.latLng),
new map.LatLng(geoResult.results[0].geometry.location)
);
return {
lat: geoResult.results[0].geometry.location.lat(),
lng: geoResult.results[0].geometry.location.lng(),
heading: newHeading,
pano: panoResult.data.location.pano,
};
};

Related

Cannot POST when sending request in Postman

I am having a small issue. I am trying to send a request in Postman, but I receive "
Cannot POST /api/logTemp/1/25
"
Here is my app.js:
const express = require('express')
const bodyParser = require('body-parser')
const cors= require('cors')
const fs= require('fs')
const path= require('path')
const morgan = require('morgan')
const router = require('./routes/route')
const app = express()
app.use(cors())
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false}))
// parse application/json
app.use(bodyParser.json())
app.use(morgan('dev'))
//create a write stream (in append mode)
var accessLogStream = fs.createWriteStream(path.join(__dirname, '/logs/access.log'), {flags: 'a'})
//setup the logger
app.use(morgan('combined', {stream: accessLogStream}))
app.use(router)
app.get('/', (req, res) => {
res.send('Hello World!')
})
const port = 3000
//app.listen(process.env.PORT || port, (err) => {
app.listen(port, () => {
console.log('Server started running on :' + port)
})
and here is my controller file:
const { getEnabledCategories } = require('trace_events');
const mysql = require('../database/db')
class MainController {
async logTemp(req, res){
console.log(req.params.temperature)
console.log(req.params.deviceID)
if(req.params.deviceID != null && req.params.temperature != null){
let deviceID = req.params.deviceID
let temperature = req.params.temperature;
var sql = `insert into log_temp (log_date, device_id, temp) values (now(),${deviceID}, ${temperature});`
mysql.query(sql, (error,data,fields) => {
if(error){
res.status(500)
res.send(error.message)
} else{
console.log(data)
res.json({
status: 200,
message: "Log uploaded successfully",
affectedRows: data.affectedRows
})
}
})
} else {
res.send('Por favor llena todos los datos!')
}
}
async getLogs(req, res){
console.log("Get Logs")
console.log(req.params.deviceID)
if(req.params.deviceID!=null){
let deviceID = req.params.deviceID;
var sql = `SELECT * FROM log_temp where device_id=${deviceID}`
mysql.query(sql, (error, data, fields) => {
if(error) {
res.status(500)
res.send(error.message)
} else {
console.log(data)
res.json({
data
})
}
})
}
}
}
const tempController = new MainController()
module.exports = tempController;
The code above was made in Visual Studio. It is odd because getLogs does work but logTemp does not. What I intend to do with logTemp is add a new value (which is the value temperature) to MySQL database. The connection to the database worked just fine, as well as localhost. If you need any more info in order to help me find a solution, please let me know and I will be more than happy to provide it. Also, i'm sorry for any grammar errors, english is not my first language :)

I am mocking two functions exactly the same way. In one case the mock value is returned and in another case the real function is called. Why?

I have a file that exports some functions:
function getNow() {
console.log('real now');
return dayjs();
}
function groupProducts(productInfos, now) {
console.log('real group');
return productInfos.reduce((groups, productInfo) => {
const groupKey = dayjs(productInfo.saleStartDate) > now ? dayjs(productInfo.saleStartDate).format('YYYY-MM-DD') : dayjs(now).format('YYYY-MM-DD');
let group = groups[groupKey];
if (!group) {
group = [];
// eslint-disable-next-line no-param-reassign
groups[groupKey] = group;
}
group.push(productInfo.itemId);
return groups;
}, {});
}
async function fetchProducts(client, productInfos, now) {
const products = [];
const groups = groupProducts(productInfos, now);
for (const [date, ids] of Object.entries(productQueryGroups)) {
// eslint-disable-next-line no-await-in-loop
const productBatch = await fetchResources(
client.queryProducts,
{
articleIds: ids,
timestamp: date,
},
);
products.push(...productBatch);
}
return products;
}
module.exports = {
test: {
getNow,
groupProducts,
fetchProducts,
},
};
I run my tests with:
package.json script
"testw": "npx ../node_modules/.bin/jest --watch",
cli command:
npm run testw -- filename
In this test I exercise groupProducts and mock getNow. The real getNow is never called and the test passes.
describe('groupProducts', () => {
it('groups productInfo ids into today or future date groups', () => {
// Arrange
const nowSpy = jest.spyOn(test, 'getNow').mockReturnValue(dayjs('2001-02-03T04:05:06.007Z'));
const expectedMap = {
'2001-02-03': ['Art-Past', 'Art-Today'],
'2002-12-31': ['Art-Future-1', 'Art-Future-2'],
'2003-12-31': ['Art-Other-Future'],
};
const productInfos = [{
itemId: 'Art-Past',
saleStartDate: '1999-01-01',
}, {
itemId: 'Art-Today',
saleStartDate: '2001-02-03',
}, {
itemId: 'Art-Future-1',
saleStartDate: '2002-12-31',
}, {
itemId: 'Art-Future-2',
saleStartDate: '2002-12-31',
}, {
itemId: 'Art-Other-Future',
saleStartDate: '2003-12-31',
}];
// Assert
const dateToIds = test.groupProductInfosByTodayOrFutureDate(productInfos, test.getNow());
// Expect
expect(dateToIds).toEqual(expectedMap);
// Restore
nowSpy.mockRestore();
});
});
In this test I exercise fetchProducts and mock groupProducts. The real groupProducts is called and the causes the test to fail.
describe('fetchProducts', () => {
it.only('calls fetchResources with the timestamp and date for every product query group', async () => {
// Arrange
const productQueryGroups = {
[test.PRICE_GROUPS.CURRENT]: ['Art-Past', 'Art-Today'],
[test.PRICE_GROUPS.FUTURE]: ['Art-Future-1', 'Art-Future-2', 'Art-Other-Future'],
};
const groupProductsSpy = jest.spyOn(test, 'groupProducts').mockReturnValue( productQueryGroups);
const fetchResourcesSpy = jest.spyOn(test, 'fetchResources').mockResolvedValue([]);
// Act
await test.fetchProducts();
// Expect
expect(test.fetchResources).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({ articleIds: [productQueryGroups[test.PRICE_GROUPS.CURRENT]], timestamp: test.PRICE_GROUPS.CURRENT }));
// Restore
groupProductsSpy.mockRestore();
fetchResourcesSpy.mockRestore();
});
});
Error message
98 | function groupProducts(productInfos, now) {
> 99 | return productInfos.reduce((groups, productInfo) => {
| ^
100 | const groupKey = dayjs(productInfo.saleStartDate) > now ? dayjs(productInfo.saleStartDate).format('YYYY-MM-DD') : dayjs(now).format('YYYY-MM-DD');
101 |
102 | let group = groups[groupKey];
Why is the real groupProducts called? To me it looks completely analogous to the previous example.

Compare node_modules for each releases

Looking for a way to compare package changes between releases.
I need a script or something that when run will show the difference (what packages are new, deleted or updated) between master tagged releases, by comparing the node_modules.
List with all changed or new packages/modules within tree of node_modules.
just came back from holiday, so this is the way I attempted a solution:
const checker = require('license-checker')
const compareVersions = require('compare-versions')
const rimraf = require('rimraf')
const { WebClient } = require('#slack/web-api')
const { exec } = require('child_process')
// An access token (from your Slack app or custom integration - xoxp, xoxb)
const token =
'xoxp-3712510934-8544rv58640-699363584817-a66630cfebf2f81e59478c3f8u0e178b'
const channel = 'where_to_post_report'
let prevReleasePackets
let currReleasePackets
function comparerVersion(otherArray) {
return current =>
otherArray.filter(other => other.name === current.name).length === 0
}
function comparerVersionNo(otherArray) {
return current =>
otherArray.filter(
other =>
other.name === current.name &&
compareVersions(other.version, current.version) === -1
).length === 0
}
function mapToData(libs) {
return Object.keys(libs)
.filter(key => key.indexOf('sm-web') === -1 && key.indexOf('debug') === -1)
.map(key => {
const lib = libs[key]
const name = lib.name
.replace(/#/g, '_')
.replace(/\./g, '_')
.replace(/\//g, '_')
const version = lib.version.replace(/#/g, '_').replace(/\//g, '_')
return {
name,
version,
}
})
}
function groupBy(objectArray, property) {
return objectArray.reduce((acc, obj) => {
const key = obj[property]
if (!acc[key]) {
acc[key] = []
}
acc[key].push(obj.version)
return acc
}, {})
}
function getPackets(path) {
return new Promise((resolve, reject) => {
checker.init(
{
start: path,
production: true,
customFormat: {
name: '',
version: '',
},
},
(err, packages) => {
if (err) {
// Handle error
console.log(err)
reject(err)
} else {
// The sorted package data
const packagesReduced = groupBy(mapToData(packages), 'name')
const higerVerionList = []
Object.keys(packagesReduced).forEach(key => {
const versions = packagesReduced[key]
const descVersions = versions.sort(compareVersions).reverse()
higerVerionList.push({ name: key, version: descVersions[0] })
})
resolve(higerVerionList)
}
}
)
})
}
function clonePrevious(tag) {
return new Promise((resolve, reject) => {
exec(
`git clone https://bitbucket.path_to_repo.git prevVersion && cd prevVersion && git checkout tags/${tag} && yarn && cd ..`,
async (error, stdout, stderr) => {
if (error) {
console.warn(error)
reject(error)
}
if (stdout) {
const prevPacks = await getPackets('./prevVersion')
resolve(prevPacks)
} else {
resolve(stderr)
}
}
)
})
}
async function sendReportToSlack(report) {
const web = new WebClient(token)
const res = await web.chat.postMessage({
channel,
text: report,
})
// `res` contains information about the posted message
console.log('Report sent: ', res.ts)
}
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
})
console.log('Deleting prevVersion folder')
rimraf('prevVersion', async () => {
console.log('Done deleting prevVersion folder')
readline.question(
`What's the version tag for previous release?`,
async tag => {
console.log(`Start cloning and shit the release ${tag}!`)
readline.close()
prevReleasePackets = await clonePrevious(tag)
currReleasePackets = await getPackets('./')
const update = currReleasePackets.filter(
comparerVersionNo(prevReleasePackets)
)
const deleted = prevReleasePackets.filter(
comparerVersion(currReleasePackets)
)
const newPacks = currReleasePackets.filter(
comparerVersion(prevReleasePackets)
)
const slackMessage =
`*Packages changes from ${tag}*:\n\n` +
`*--Updated--*: ${JSON.stringify(
update
)},\n\n *--Deleted--*: ${JSON.stringify(
deleted
)} \n\n *--New--*: ${JSON.stringify(newPacks)}`
await sendReportToSlack(slackMessage)
}
)
})

Google Cloud functions (with Pubsub) error

We are using GCP with Cloud functions (with Pubsub topic triggers), and though it works fine most of the time, we do see it often throwing the following authentication error:
Error: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
at (/user_code/node_modules/#google-cloud/pubsub/node_modules/grpc/src/node/src/client.js:569)
Has anyone seen this or know what causes it or how to fix?
Cloud function code:
require('dotenv').config()
const datastore = require('#google-cloud/datastore')()
const pubsub = require('#google-cloud/pubsub')()
const promiseRetry = require('promise-retry')
const elasticsearch = require('elasticsearch')
const SupplierSearchManager = require('shared-managers').SupplierSearchManager
const BaseManager = require('shared-managers').BaseManager
const Util = require('shared-managers').Util
const StatsManager = require('shared-managers').StatsManager
var unitTestMode = false
var searchManagerMock, pubsubMock
exports.setUnitTestMode = (searchManagerMockP, pubsubMockP) => {
unitTestMode = true
searchManagerMock = searchManagerMockP
pubsubMock = pubsubMockP
}
exports.updateElastic = event => {
let dataObject
try {
dataObject = JSON.parse(Buffer.from(event.data.data, 'base64').toString())
} catch (err) {
console.log(err)
console.log(event.data.data)
return Promise.reject(err)
}
const baseManager = new BaseManager(datastore, new Util('base-manager'), pubsub)
const statsManager = new StatsManager(baseManager, new Util('stats-manager'))
let supplierId = dataObject.supplierId
let retryCount = dataObject.retryCount
let refresh = dataObject.refresh === true
if (!retryCount) retryCount = 0
return new Promise((resolve, reject) => {
let elasticClient = new elasticsearch.Client({
host: process.env.ELASTIC_HOST,
httpAuth: process.env.ELASTIC_AUTH
})
const supplierSearchManager = unitTestMode ? searchManagerMock : new SupplierSearchManager(elasticClient, baseManager, statsManager)
supplierSearchManager.indexSupplier(process.env.ELASTIC_INDEX, supplierId, refresh).then(resolve, err => {
console.log(err)
if (retryCount < 2) {
const topic = unitTestMode ? pubsubMock : pubsub.topic(process.env.PUBSUB_PREFIX + process.env.PUBSUB_TOPIC_ELASTIC)
promiseRetry({retries: 4, maxTimeout: 8000}, (retry, number) => {
return topic.publish({ supplierId: supplierId, retryCount: retryCount + 1 }).catch(err => {
retry(err)
})
}).then(resolve, err => {
console.log(err)
reject(err)
})
} else {
resolve(true)
}
})
})
}

InvalidRequestException of status code 400 when AWS Lambda Function was invoked

var config = {};
config.IOT_BROKER_ENDPOINT = "abcdefghijk.iot.us-east-1.amazonaws.com".toLowerCase();
config.IOT_BROKER_REGION = "us-east-1";
config.IOT_THING_2 = "Thing1";
var AWS = require('aws-sdk');
AWS.config.region = config.IOT_BROKER_REGION;
AWS.config.update({accessKeyId: 'xxxxxxxxxxxxxxxxxxxx', secretAccessKey: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'});
var iotdata = new AWS.IotData({endpoint: config.IOT_BROKER_ENDPOINT});
// namespaces
const NAMESPACE_CONTROL = "Alexa.ConnectedHome.Control";
const NAMESPACE_DISCOVERY = "Alexa.ConnectedHome.Discovery";
// discovery
const REQUEST_DISCOVER = "DiscoverAppliancesRequest";
const RESPONSE_DISCOVER = "DiscoverAppliancesResponse";
// control
const REQUEST_TURN_ON = "TurnOnRequest";
const RESPONSE_TURN_ON = "TurnOnConfirmation";
const REQUEST_TURN_OFF = "TurnOffRequest";
const RESPONSE_TURN_OFF = "TurnOffConfirmation";
// errors
const ERROR_UNSUPPORTED_OPERATION = "UnsupportedOperationError";
const ERROR_UNEXPECTED_INFO = "UnexpectedInformationReceivedError";
// entry
exports.handler = function (event, context, callback) {
log("Received Directive", event);
var requestedNamespace = event.header.namespace;
var response = null;
try {
switch (requestedNamespace) {
case NAMESPACE_DISCOVERY:
response = handleDiscovery(event);
break;
case NAMESPACE_CONTROL:
response = handleControl(event);
break;
default:
log("Error", "Unsupported namespace: " + requestedNamespace);
response = handleUnexpectedInfo(requestedNamespace);
break;
}// switch
} catch (error) {
log("Error", error);
}// try-catch
callback(null, response);
}// exports.handler
var handleDiscovery = function (event) {
var header = createHeader(NAMESPACE_DISCOVERY, RESPONSE_DISCOVER);
var payload = {
"discoveredAppliances": [],
};
return createDirective(header, payload);
}// handleDiscovery
var handleControl = function (event) {
var response = null;
var requestedName = event.header.name;
switch (requestedName) {
case REQUEST_TURN_ON :
response = handleControlTurnOn(event);
break;
case REQUEST_TURN_OFF :
response = handleControlTurnOff(event);
break;
default:
log("Error", "Unsupported operation" + requestedName);
response = handleUnsupportedOperation();
break;
}// switch
return response;
}// handleControl
var handleControlTurnOn = function (event) {
var thingPicker = config.IOT_THING_2;
console.log("Turning On the LED now");
console.log("check 1");
var update = {
"desired": {
"led": 1,
},
};
console.log("check 2");
console.log(thingPicker);
iotdata.updateThingShadow({
payload: JSON.stringify(update),
thingName: thingPicker,
}, function (err, data) {
console.log("check 4");
if (err) {
console.log("check 5");
console.log(err);
} else {
console.log("check 6");
console.log(data);
}
});
var header = createHeader(NAMESPACE_CONTROL, RESPONSE_TURN_ON);
var payload = {};
return createDirective(header, payload);
}// handleControlTurnOn
var handleControlTurnOff = function (event) {
var thingPicker = config.IOT_THING_2;
console.log("Turning Off the LED now");
var update = {
"desired": {
"led": 0,
},
};
console.log(thingPicker);
iotdata.updateThingShadow({
payload: JSON.stringify(update),
thingName: thingPicker,
}, function (err, data) {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
var header = createHeader(NAMESPACE_CONTROL, RESPONSE_TURN_OFF);
var payload = {};
return createDirective(header, payload);
}// handleControlTurnOff
var handleUnsupportedOperation = function () {
var header = createHeader(NAMESPACE_CONTROL, ERROR_UNSUPPORTED_OPERATION);
var payload = {};
return createDirective(header, payload);
}// handleUnsupportedOperation
var handleUnexpectedInfo = function (fault) {
var header = createHeader(NAMESPACE_CONTROL, ERROR_UNEXPECTED_INFO);
var payload = {
"faultingParameter": fault,
};
return createDirective(header, payload);
}// handleUnexpectedInfo
// support functions
var createMessageId = function () {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
return uuid;
}// createMessageId
var createHeader = function (namespace, name) {
return {
"messageId": createMessageId(),
"namespace": namespace,
"name": name,
"payloadVersion": "2",
};
}// createHeader
var createDirective = function (header, payload) {
return {
"header": header,
"payload": payload,
};
}// createDirective
var log = function (title, msg) {
console.log('**** ' + title + ': ' + JSON.stringify(msg));
}// log
Piece of code related to AWS Lambda Function which is of smart home API, when it was run against a testing event to turn on light, its giving "InvalidRequestException" of status code :400
the test event that was run against the code was:
{
"header": {
"messageId" : "5d599a53-fe40-405f-b0ab-233611e2dc5c",
"name" : "TurnOnRequest",
"namespace" : "Alexa.ConnectedHome.Control",
"payloadVersion" : "2"
},
"payload" : {
"accessToken" : "acc355t0ken"
}
}
Can any one please help me solve that exception.
Thanks in advance