Im using geocode api from google maps and Im trying to use the answer from server to fill up a form, the problem is, it's not a pattern of object, the result[0].address_components sometimes return 4, 5 and 7 obj and I can`t to know with one is the city, country etc, there is some way to get like result.something.street, result.something.city etc?
else{
Geocode.fromAddress(cep).then(
response => {
const { lat, lng } = response.results[0].geometry.location;
console.log(response.results[0].address_components);
console.log(response);
},
error => {
console.error(error);
}
);
}
You need to filter the object
Working Fiddle
function getValue(adress_components, component_name) {
return adress_components.filter(c => c.types[0] == component_name)[0].long_name
}
var components = response.results[0].address_components;
console.log(getValue(components, 'street_number'));
console.log(getValue(components, 'locality'));
console.log(getValue(components, 'country'));
console.log(getValue(components, 'postal_code'));
Related
I am trying to make a request to the Google Directions API with multiple waypoints. Everything works fine so far, but the main problem that I'm having is that when the Google Maps app is open for the user, all that the user can see are the coordinates.
I am working on a Flutter App, but probably this request is the same for all devices and platforms, so it's not really Flutter-specific.
I want to show the name of the companies/places on the route.
It could be either a web request or a request using the URL scheme for the Google Maps mobile app.
This is what I'm doing so far, with the coordinates.
Future<void> launchGoogleMaps(BuildContext context) async {
Position userLocation = await Geolocator().getLastKnownPosition(
desiredAccuracy: LocationAccuracy.bestForNavigation,
);
String googleMapsAppUrl = 'comgooglemapsurl://?';
if (customFirstPlace != null) {
googleMapsAppUrl +=
"saddr=${customFirstPlace.latitude},${customFirstPlace.longitude}";
} else if (!shouldStartWithUserLocation) {
googleMapsAppUrl +=
"saddr=${circuitCompanies[0].lat},${circuitCompanies[0].lng}";
}
String googleMapsWebUrl = "http://www.google.com/maps/dir";
googleMapsWebUrl += "/${userLocation.latitude},${userLocation.longitude}";
circuitCompanies.forEach((CompanyModel element) {
int elementIndex = circuitCompanies.indexOf(element);
// If it's the first element, the "direction"
// parameter will be added to specify the beginning.
// If not, the "to" parameter will be added
// to specify a waypoint (a stop).
if (elementIndex == 0) {
googleMapsAppUrl += "&daddr=${element.lat},${element.lng}";
} else {
googleMapsAppUrl += "+to:${element.lat},${element.lng}";
}
googleMapsWebUrl += "/${element.lat},${element.lng}";
});
if (await canLaunch("comgooglemaps://")) {
print('launching com googleUrl $googleMapsAppUrl');
await launch(googleMapsAppUrl);
} else if (await canLaunch(googleMapsWebUrl)) {
print('launching web url $googleMapsWebUrl');
await launch(googleMapsWebUrl);
} else {
showDialog(
builder: (_) {
return SingleActionDialog(
title: "Erreur",
onConfirmTap: () => Navigator.pop(context),
bodyText: "Un erreur s'est produit.",
confirmText: "Fermer",
);
},
context: context,
);
}
}
How could I show the appropriate route, with the name of the places that the user will go, instead of only showing the coordinates? I have access to the precise place address as well.
Thanks!
I managed to solve this issue. I instead used the web URL provided by the Google Maps API.
I made a function that returns the address of the place following the Google Maps standard, instead of just passing coordinates.
Future<String> getEncodedCompanyAddress(CompanyModel model) async {
String _encodedAddress = "";
model.address = await CompanyAddressDAO().getCompanyAddress(
model.id,
);
_encodedAddress = model.details.title +
", " +
model.address.street +
", " +
model.address.city +
", " +
model.address.state;
_encodedAddress = Uri.encodeFull(_encodedAddress);
_encodedAddress = _encodedAddress.replaceAll("%20", "+");
return _encodedAddress;
}
Now, instead of showing only the coordinates, the actual place name is shown in the directions of the Google Maps app.
I'll preface this saying I'm a UX Designer that's new to React.
I'm using Expo/React-Native and using the "Location" feature to get the device's location information. I'm able to get the information back in a JSON object by using:
const { height, width } = Dimensions.get("window");
class Explore extends Component {
static navigationOptions = {
header: null
};
state = {
locationResult: ""
};
componentDidMount() {
this._getLocationAsync();
}
_getLocationAsync = async () => {
let { status } = await Permissions.askAsync(Permissions.LOCATION);
if (status !== "granted") {
this.setState({
locationResult: "Permission to access location was denied"
});
}
let location = await Location.getCurrentPositionAsync({});
let geocode = await Location.reverseGeocodeAsync(location.coords);
this.setState({ locationResult: JSON.stringify(geocode) });
};
And in my render I'm calling the value using:
<WelcomeText>
Discover {this.state.locationResult}
</WelcomeText>
Which returns the object:
[{"street":"Stockton St","city":"San Francisco","region":"CA","country":"United States","postalCode":"94108","isoCountryCode":"US","name":"1 Stockton St"}]
But how do I go about just displaying the value of "City" that's in the object?
Try this:
<WelcomeText>
Discover {this.state.locationResult[0].city}
</WelcomeText>
Explanation:
Your this.state.locationResult is an array of objects. With this.state.locationResult[0] we are accessing the first object. Then we can use the . operator to access the property we want. In your case .city
Edit:
You need to pass in geocode without stringifying it, otherwise you cannot access it like i described it above. reverseGeocodeAsync is already returning an array of objects, no need to transform it to a string.
Replace:
this.setState({ locationResult: JSON.stringify(geocode) });
with:
this.setState({ locationResult: geocode });
Edit2:
Here is a working example: https://snack.expo.io/B1SqSd3iN
I'm working with Angular 4+.
I've added an API that fetches the company list. Against that company list, I'm fetching services that specific company booked.
For fetching the list of services that specific company booked I've created a function getCompanyServices() and called it in ngOnInit my API looks like this:
www.example.com/company-service/255 where 255 is the id of the company being fetched by another api.
If I simply show {{company.id}} in html view it displays the id but how do I concatenate that company.id in the api url of get company services?
Approaches I've tried:
Create a variable, company_id in my component.ts file assigned it data.company-id but the data doesn't parse.
Pass company id in the function where I'm calling my getCompanyServices() api but I'm unable to understand how to parse the data into it.
Code:
demo.service.ts (for hitting apis)
getCompanies() {
return this.http.get('http://example.com/api/companies', httpOptions);
}
getCompanyServices() {
return this.http.get('http://example.com/v1/company-service', httpOptions);
}
services.component.ts file
companies: any=[];
services: any=[];
ngOnInit() {
this.getCompanies();
this.getCompanyServices();
}
getCompanies() {
this._demoService.getCompanies().subscribe(
(response:any) => { console.log("Response =" , response);
this.companies = response.data;
},
err => { console.error(err)},
() => { console.log("ALL Companies FETCHED!") }
)
}
getCompanyServices() {
this._demoService.getCompanyServices().subscribe(
(response:any) => { console.log("Response =" , response);
this.services = response.data;},
err => { console.error(err)},
() => { console.log("Services FETCHED!") }
)
}
HTML file
<p>{{company.id}}</p>
<p>{{company.name}}</p>
<button class="sidebar-services">Services</p>
You may do the second call when the first will resolve to take all the companies list in your app then you can request the company specific service information.
In ngOninit
this.getcountries().subscribe(data=>{
// your stuff
this.getCompanyServices(id) // the company id that
you need
.subscribe(...
Getcompanyservice definition
`
getCompanyServices(id) {
this._demoService.getCompanyServices(id).subscribe(
(response:any) => { console.log("Response =" , response);
this.services = response.data;},
err => { console.error(err)},
() => { console.log("Services FETCHED!") }
)
}
`
In the service
`getCompanyServices(id) {
return this.http.get(`http://example.com/v1/company-service/${id}, httpOptions);
}`
Based on what I understand from your question, what you need is to get companyId and for each companyId get its services. You can achieve it by using flatMap as below:
this.subsc = this._demoService.getCompanies()
.pipe(flatMap((s) => {
this.companies.push(s);
return s.id;
}),
flatMap((id) =>{
return this._demoService.getCompanyServices(id).pipe(map((services) => {
return services;
}));
}))
.subscribe(res => {
this.services.push(res);
},
undefined,
() => console.log('complete'));
I mimicked demo here: https://stackblitz.com/edit/angular-xwsltm
You can use promises, fetch the data and do another call..
if im not mistaken you can do something like that
this.http.get('http://example.com/api/companies', httpOptions)
.timeout(15000)
.map(res => res.json()) // you might not need this line
.toPromise()
.then(compList => {
//here you have the company list
console.log('compList', compList); // check your developer tools to see the list
this.http.get('www.example.com/company-service/' + x, httpOptions) //where x should be substituted with the id of the desired company
}
If you dont want to change the implementation you already have then wrap each of the functions used with a Promise and just call the function and .then it
will become something like getCompanies().then(...
if you need me to explain more or something just comment..
Hope this helped
I have a service with a method called "getGmapsDistance()". Here im using the google maps api to get the distance between an origin an an destination.
export default Ember.Service.extend({
getShortestDistanceInMeters: function(location) {
var service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix({
...
}, this.callback); //<<<<<< !!!
},
callback: function(response, status) {
....
}
});
In my controller if got a array with locations and now I want to iterate over it and want check each element if the distance is <= the max destination.
locationsNearby: Ember.computed('locations', function() {
//...
var filteredResult = [];
locations.forEach(function(locat) {
if (this.get('distanceService').getShortestDistanceInMeters(locat) <= maxDistance) {
filteredResult.pushObject(locat);
}
});
return filteredResult;
})
Unfortunately the GMaps API for distance calculation uses a callback so the request is async.
How can I solve that problem?
You can not make an async call synchronous! This is an javascript language limitation and is important to understand! Javascript has only one thread, so this can't be changed by a library or so!
The fancy new way to handle callbacks are Promises.
You really really should checkout the specifications!
It's one of the most beautiful specifications you will ever read!
Ember uses Promises heavily! For example a routes model hook waits for a Promise to resolve before going on with the transition.
In your case you want to update the computed property when the promise resolves. Because ember-data causes this to happen often they provide two fancy classes: PromiseObject and PromiseArray. A computed property depending on a computed property that returns a PromiseObject/Array will recompute when the promise resolves:
locationsNearby: Ember.computed('locations', {
get() {
let promise = Ember.RSVP.all(this.get('locations').map(location => Ember.RSVP.hash(({
location,
distance: this.get('distanceService').getShortestDistanceInMeters(location)
})))).then(hashs => hashs.filter(hash => hash.distance <= maxDistance).map(hash => hash.location));
return DS.PromiseArray.create({promise});
}
})
To explain it a little:
I build an array with hash's of the location and a promise to the distance:
let locationsWithDistancePromise = this.get('locations').map(location => {
distance: this.get('distanceService').getShortestDistanceInMeters(location),
location
})
Then I use RSVP.hash on all of them to get an array of promises that will resolve to an array of hashes with distance and location:
let hashPromiseArr = locationsWithDistancePromise.map(h => Ember.RSVP.hash(h));
Now I use Ember.RSVP.all to get an promise that will resolve to an array of hashes with location and distance:
let hashArrPromise = Ember.RSVP.all(hashPromiseArr);
An finally I .then on the promise and filter the nearby locations. Also I map the hash to a array of locations.
let promise = hashArrPromise.then(hashs => {
return hashs.filter(hash => hash.distance <= maxDistance)
.map(hash => hash.location);
});
And wrap it as an PromiseArray
return DS.PromiseArray.create({promise});
You can just loop over this Computed Property from handlebars with {{#each}} or use it in another Computed Property:
allNearbyLocations: Ember.computed('locationsNearby.[]', {
get() {
return this.get('locationsNearby').toArray().join(' - ');
}
}
Of course you need to rewrite getShortestDistanceInMeters so that it returns a Promise:
getShortestDistanceInMeters(location) {
var service = new google.maps.DistanceMatrixService();
return new Ember.RSVP.Promise((resolve, reject) => {
service.getDistanceMatrix({
//...
}, (response, status) => {
if(status.error) {
reject(response);
} else {
resolve(response);
}
});
});
}
I'm using NodeJS and an npm package called oauth to communicate with Twitter's search API. For some reason however, twitter is returning to me an empty array of statuses without any error... What is even more confusing is the fact that using a tool like Postman with the exact same request and keys returns the list of tweets? It makes no sense! Here is my request:
URL: https://api.twitter.com/1.1/search/tweets.json?count=100&q=hello&since_id=577103514154893312&max_id=577103544903462913
Here is my code:
var twitter_auth = new OAuth(
"https://api.twitter.com/oauth/request_token",
"https://api.twitter.com/oauth/access_token",
config.consumer_key,
config.consumer_secret,
"1.0A",
null,
"HMAC-SHA1"
);
var request = twitter_auth.get(
"https://api.twitter.com/1.1/search/tweets.json" + url,
config.access_token,
config.access_token_secret
);
var chunk = "", message = "", that = this;
request.on("response", function(response){
response.setEncoding("utf8");
response.on("data", function(data){
chunk += data;
try {
message = JSON.parse(chunk);
} catch(e) {
return;
}
console.log(message);
if(message.statuses)
{
for(var i = 0; i < message.statuses.length; i++)
{
var tweet = message.statuses[i];
that.termData[term.name].push(tweet);
}
if(message.search_metadata.next_results)
{
that.openRequests.push(that.createNewSearch(message.search_metadata.next_results, term));
}
else
{
that.termCompleted(term);
}
}
else if(message)
{
console.log("Response does not appear to be valid.");
}
});
response.on("end", function(){
console.log("Search API End");
});
response.on("error", function(err){
console.log("Search API Error", err);
});
});
request.end();
The console.log(message) is returning this:
{
statuses: [],
search_metadata: {
completed_in: 0.007,
max_id: 577103544903462900,
max_id_str: '577103544903462913',
query: 'hello',
refresh_url: '?since_id=577103544903462913&q=hello&include_entities=1',
count: 100,
since_id: 577103514154893300,
since_id_str: '577103514154893312'
}
}
Any ideas what is going on? Why is the statuses array empty in my code but full of tweets in Postman?
This issue was described at twittercommunity.com.
Accordingly answer of user rchoi(Twitter Staff):
"Regarding web vs. API search, we're aware that the two return different results at the moment. We made upgrades to the web search. There is no timeline for those
changes to be brought to other parts of our system."
Try to use
https://dev.twitter.com/rest/reference/get/statuses/mentions_timeline
https://dev.twitter.com/rest/reference/get/statuses/user_timeline
if you get empty result with api search functionality.
Please follow this link
https://twittercommunity.com/t/search-tweets-api-returned-empty-statuses-result-for-some-queries/12257/6