GeoCoder gives default value for invalid zip codes - zip

I am using Geocoder to get a location based on the ZIP code (I am restricting it to just the US). Everything works fine except that if I input an invalid zip (90123, for example), it gives me a default value instead of giving ZERO_RESULTS. The default value happens to be Denton, Texas (for all invalid codes). How can I prevent this from happening, or tell whether a code is invalid to avoid this issue?
I am using this code:
geocoder.geocode({ 'address': zip, componentRestrictions: {country: 'us'} }, function (results, status) {
if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
jQuery('#zipErrorId').html("INVALID");
}
if (status == google.maps.GeocoderStatus.OK) {
geocoder.geocode({'latLng': results[0].geometry.location}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
var cityState = getCityState(results);
// like Apple Valley, Minnesota
var cityStateArr = cityState.split('|');
---------------------------
}
}
});
}

Currently it is returning Prudential Tower in Boston, MA. Don't know why.
It sends back the value you entered. So in results.address_components.short_name, will be the value it returned. So for example if I search on "00000,United States", the results.address_components.short_name will be "02199" (the zip of the aforementioned building). If that doesn't match the value you gave it, it was probably an invalid zip.

Related

Unable to add event listener to webNavigation.onCompleted

Using the mock function below along with the dev console:
This call will work:
chrome.webNavigation.onCompleted.addListener(processWebNavChange, filtera);
but when I actually pass in my real var filter it throws this error:
Uncaught TypeError: Could not add listener
My actual data looks like this:
{
url: [ {hostContains: ".im88rmbOwZ"} ]
}
function registerWebNavListener() {
var matchers = getUrlMatchers();
var filter = {
url: matchers
};
// test with mock data filtera that actually works
const filtera = {
url:
[
{hostContains: "example.com"},
]
}
if (matchers.length > 0) {
chrome.webNavigation.onCompleted.addListener(processWebNavChange, filtera);
}
}
async function processWebNavChange(data) {
}
Is there something wrong with my data structure that I'm actually using? I don't believe that the filter object I returned is incorrect
}
EDIT:
I added a new
const filterb = {
url: [ {hostContains: ".im88rmbOwZ"} ]
};
and it still fails with that. The single entry {hostContains: ".im88rmbOwZ"}, was the first item returned from getURLMatchers() which I used as an example of real data being returned.
The above comment on the upper-case letters was the cause of the issue. Converting everything to lowercase resolved the problem.
Although, I am not clear as to why that was a problem to begin with. (If there are any hints in the chromium source code event filter handlers, I'd appreciate it if it could be pointed out).

How can I pass collected values to a replanned action?

When the user says "read john 3:100", I have a ReadBibleVerse action that matches book:john, chapter:3, verse:100. The endpoint will return a 404, since there is no verse 100.
I want that action to capture the error and replan to a "read chapter" request, passing along book:john and chapter:3.
What I have...
action (ReadBibleVerse) {
collect {
input (book) {…}
input (chapter) { type (ChapterNum) … }
input (verse) {…}
}
output (Scripture) {
throws {
unknown-error {
on-catch {
replan {
dialog ("Unknown verse, trying the chapter.")
intent {
goal: Scripture
route: ReadBibleChapter
}}}}}}}
…what I get is "Unknown verse, trying the chapter. I need a book to continue."
I'm clearly hitting the error and, I believe, being "replanned" to ReadBibleChapter, but I'm also getting "I need a book to continue." because I need to explicitly pass along book and chapter?
I found intent.value, which appears to solve my problem, except I can't seem to find the correct format:
value: ChapterNum
value: ChapterNum (chapter)
value: [namespace].ChapterNum { $expr(chapter) }
more various nonsense
…
This should work value {$expr(chapter)}

If statements not working with JSON array

I have a JSON file of 2 discord client IDs `{
{
"premium": [
"a random string of numbers that is a client id",
"a random string of numbers that is a client id"
]
}
I have tried to access these client IDs to do things in the program using a for loop + if statement:
for(i in premium.premium){
if(premium.premium[i] === msg.author.id){
//do some stuff
}else{
//do some stuff
When the program is ran, it runs the for loop and goes to the else first and runs the code in there (not supposed to happen), then runs the code in the if twice. But there are only 2 client IDs and the for loop has ran 3 times, and the first time it runs it goes instantly to the else even though the person who sent the message has their client ID in the JSON file.
How can I fix this? Any help is greatly appreciated.
You may want to add a return statement within your for loop. Otherwise, the loop will continue running until a condition has been met, or it has nothing else to loop over. See the documentation on for loops here.
For example, here it is without return statements:
const json = {
"premium": [
"aaa-1",
"bbb-1"
]
}
for (i in json.premium) {
if (json.premium[i] === "aaa-1") {
console.log("this is aaa-1!!!!")
} else {
console.log("this is not what you're looking for-1...")
}
}
And here it is with return statements:
const json = {
"premium": [
"aaa-2",
"bbb-2"
]
}
function loopOverJson() {
for (i in json.premium) {
if (json.premium[i] === "aaa-2") {
console.log("this is aaa-2!!!!")
return
} else {
console.log("this is not what you're looking for-2...")
return
}
}
}
loopOverJson()
Note: without wrapping the above in a function, the console will show: "Syntax Error: Illegal return statement."
for(i in premium.premium){
if(premium.premium[i] === msg.author.id){
//do some stuff
} else{
//do some stuff
}
}
1) It will loop through all your premium.premium entries. If there are 3 entries it will execute three times. You could use a break statement if you want to exit the loop once a match is found.
2) You should check the type of your msg.author.id. Since you are using the strict comparison operator === it will evaluate to false if your msg.author.id is an integer since you are comparing to a string (based on your provided json).
Use implicit casting: if (premium.premium[i] == msg.author.id)
Use explicit casting: if (premium.premium[i] === String(msg.author.id))
The really fun and easy way to solve problems like this is to use the built-in Array methods like map, reduce or filter. Then you don't have to worry about your iterator values.
eg.
const doSomethingAuthorRelated = (el) => console.log(el, 'whoohoo!');
const authors = premiums
.filter((el) => el === msg.author.id)
.map(doSomethingAuthorRelated);
As John Lonowski points out in the comment link, using for ... in for JavaScript arrays is not reliable, because its designed to iterate over Object properties, so you can't be really sure what its iterating on, unless you've clearly defined the data and are working in an environment where you know no other library has mucked with the Array object.

Protractor: Is it possible to check if an element doesn't contain certain text?

On the page that I am testing, a user can have a single currency or multiple currencies (i.e EUR and USD)the currency/currencies will appear in the same div at the top of the page.
If a user has multiple currencies, a tab for each currency will appear further down the page, if a user has only one currency, no tabs will appear (as there is no need for the user to switch tabs).
I am able to test multi currency users by checking to see if the text contained in the header matches the text contained in the currencies tabs.
However, as no tabs appear for a single currency, I'm not sure how to test this.
For example, if I have only a 'EUR' currency, is there a way to do something like
if element(by.className("currencies"))contains 'EUR'
&& doesn't contain 'USD' && doesn't contain 'GBP'
expect element(by.className("tabs").toDisplay.toBeFalsy()
This is the code for the page object file
this.checkCurrency = function(currency) {
var checkBalance = element(by.className("balances"));
checkBalance.getText().then(function (text) {
if (text.indexOf("GBP" && "EUR")>= 0) {
expect(element.all(by.linkText("GBP")).isDisplayed()).toBeTruthy();
console.log("EUR GBP buyer");
}
else if (text.indexOf("GBP" && "USD")>= 0) {
expect(element.all(by.linkText('USD')).isDisplayed()).toBeTruthy();
console.log("USD GBP buyer");
}
else
{
console.log("false");
}
});
};
From your description I'm not quite sure where the failure is. In general you want to keep this kind of logic out of your page object. Your test should understand what state the page should be in and call different functions. I know that's not always possible, but it works out so much better if you can. Here is some general condition advise that should help.
You can catch the success state and a failed state of a promise. Most people use the pass function, but forget about the fail function.
promise.then(passFunction, failFunction)
You can use this in several different ways. If you realize that almost everything in protractor is returning a promise.
Example:
element(by.className("currencies")).getText()
.then(
function(text) {
//check on something
},function(error){
//don't check on something
if(someCondition) {
throw error;
} else {
//the test continues
}
});
You can even do it with and expect
expect(element(by.className("currencies")).getText()).not.toContain("EUR")
.then(
function(passed) {
//check on something
},function(failed){
//don't check on something
if(someCondition) {
throw failed;
} else {
//the test continues
}
});
Or a simple findElement
element(by.className("currencies"))
.then(
function(element) {
//check on something
},function(error){
//don't check on something
if(someCondition) {
throw failed;
} else {
//the test continues
}
});

get the document url in chrome.webRequest.onBeforeRequest

In chrome.webRequest.onBeforeRequest we get all sorts of url's -- javascript, css etc.
For every url I want to know the main tab url.
What is the simplest way to get it synchronously?
Right now I'm using this way:
if details.frameId == 0 then details.url contains the main tab url for this tab id
chrome.webRequest.onBeforeRequest.addListener(
function (details) {
if (details.tabId == -1)
{
return;
}
if ("type" in details && ['main_frame', 'sub_frame'].indexOf(details.type) !== -1)
{
if (details.frameId == 0) {
all_tabs_info.add_tab_info(details.tabId, details.url);
}
}
},
{
urls: ['<all_urls>']
},
["blocking"]);
So now onwards if any request comes for this tab id we already have the tab url. This crude logic seems to be working.
A couple of enhancements:
use filters as much as possible, in this case for type.
main_frame type by definition corresponds to the top-level frame, which in turn means it has frameId of 0, so by not listening to sub_frame you can omit the check altogether.
The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab.
type is not optional as you can see in the documentation, no need to doubt its presence.
So the simplified code is just this:
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
if (details.tabId >= 0) {
all_tabs_info.add_tab_info(details.tabId, details.url);
}
},
{
urls: ['<all_urls>'],
types: ['main_frame'],
},
["blocking"]
);

Resources