Query esri search widget - javascript

this is the sample search widget in arcGIS, I want to override the search function, that the only thing that can be searched is the data in my query and it will appear just like in the picture
const [searchData, setSearchData] = useState(null);
const fetchSearchLocation = async (name) => {
const { data } = await client.query({
query: SEARCH_LOCATION,
variables: {
name: name
},
})
setSearchData(data);
return data;
};
useEffect(() => {
location();
}, []);
const location = () => {
if (mapDiv.current) {
esriConfig.apiKey = "sample api key";
const map = new Map({
basemap: 'arcgis-light-gray',
});
const view = new MapView({
center: [123.5504, 12.3574], // Longitude, latitude
container: mapDiv.current,
map: map,
zoom: 2, // Zoom level
});
const searchWidget = new Search({
view: view,
sources: [customSearchSource],
includeDefaultSources: false
});
view.ui.add(searchWidget, { position: "top-left", index: 0 });
view
.when((r) => {})
.then(() => {
mapDiv.current = view;
fetchData();
});
}
};
const searchDataLocation = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("searchData: ", searchData)
resolve(searchData); //test_data = Your data.
}, 1000);
});
const customSearchSource = new SearchSource({
placeholder: 'Search',
getSuggestions: (params) => {
fetchSearchLocation(params.suggestTerm)
console.log("searchData2: ", searchData)
return searchDataLocation.then((data) => {
console.log("datas: ", data) // the result is null.
})
....
resource
https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Search.html
How to put queries in ArcGIS esri search?
note: this is edited question

Related

I am trying to wait for data from firebase before running last line in a function

I'm trying to get longitude and latitude from firebase firestore and then use the data to calculate distance but the function doing the calculations runs before the data has been retrieved from firebase,please help I am new to react native and JavaScript.
function fetchProducts() {
const myProduct = [];
db.collection("item")
.orderBy("createdAt", "desc")
.get()
.then((snapshot) => {
snapshot.docs.forEach((doc) => {
const { createdAt, category, image, values, latitude, longitude } =
doc.data();
myProduct.push({
createdAt,
id: doc.id,
latitude,
longitude,
category,
image,
values,
});
});
setNewProduct(myProduct);
myData();
});
}
const myData = () => {
myNewProduct = newProduct;
GetCurrentLocation().then(() => {
myNewProduct.forEach((element) => {
mydistance = calcDistance(
element.latitude,
element.longitude,
newLatitude,
newLongitude
);
element.distance = mydistance;
});
myNewProduct.sort((a, b) => a.distance - b.distance);
setProduct(myNewProduct);
});
};

leaflet routing machine - handle errors

How can I handle not existing route in leaflet routing-machine?
In case of error I do not want to return <RoutingMachine />
const Routing = ({ pointA, pointB }) => {
const dispatch = useDispatch()
const createLayer = () => {
const instance = L.Routing.control({
waypoints: [
L.latLng(pointA.position.lat, pointA.position.lng),
L.latLng(pointB.position.lat, pointB.position.lng)
],
lineOptions: {
styles: [{ color: "#965de9", weight: 5 }]
},
});
instance.on('routesfound', (e) => {
let routes = e.routes;
let summary = routes[0].summary;
let totalTime = moment.utc(1000 * summary.totalDistance).format("H[h] mm[m]")
console.log('total time: ', totalTime);
let totalDistance = Math.floor(summary.totalDistance / 1000)
dispatch(setTime(totalTime))
dispatch(setDistance(totalDistance))
});
return instance;
};
const RoutingMachine = createControlComponent(createLayer);
return <RoutingMachine />
};

Wait until useState object has value

I've made a custom hook, which can be used to fetch users location and find nearest marker on map based on that information.
Right now it works, but first object it returns is useStates default value. Response looks like this:
{
coordinates: { lat: '', lng: '' },
loaded: false
}
After returning object first time, it starts to work like it should:
{
coordinates: { lat: 45.024335, lng: 19.277089 },
loaded: true
}
So basically I don't want that the hook sends empty objects, with no values. How can I fix this?
const useGeoLocation = (markers) => {
const [location, setLocation] = useState({
loaded: false,
coordinates: { lat: "", lng: "" },
});
const onSuccess = (location) => {
// User location succesfully fetched, converting data format.
const targetPoint = turf.point([
location.coords.latitude,
location.coords.longitude,
]);
// Fetching data from markers parameter and converting data format.
var arr = [];
markers.map((marker) => arr.push(turf.point(marker.location)));
var points2 = turf.featureCollection(arr);
// Calculating which marker is nearest to targetPoint.
var nearest = turf.nearestPoint(targetPoint, points2);
// Setting location of nearest marker to usestate.
setLocation({
loaded: true,
coordinates: {
lat: nearest.geometry.coordinates[0],
lng: nearest.geometry.coordinates[1],
},
});
};
const onError = () => {
setLocation({
loaded: true,
coordinates: {
lat: 65.024335,
lng: 27.277089,
},
});
};
useEffect(() => {
if (markers) {
if (!("geolocation" in navigator)) {
onError();
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}
}, [markers]);
return location;
};
Instead of just returning the location object as a whole, you could split the return into an object with values for the data, a loading state, an error message if needs be. For example:
const useGeoLocation = (markers) => {
const [location, setLocation] = useState(undefined);
const [error, setError] = useState("");
const onSuccess = (location) => {
// Rest of the success handler...
setLocation({
coordinates: {
lat: nearest.geometry.coordinates[0],
lng: nearest.geometry.coordinates[1],
},
});
};
const onError = () => {
setLocation({
coordinates: {
lat: 65.024335,
lng: 27.277089,
},
});
setError("Some error message");
};
useEffect(() => {
if (markers) {
if (!("geolocation" in navigator)) {
onError();
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}
}, [markers]);
return {
data: location,
isLoading: !location && !error,
error: error,
};
};
Then when calling the hook you can do:
const {data, isLoading, error} = useGeoLocation();
and check for the value of data, or that isLoading and error are false, before doing anything.

React won't loop through state in render

I'm fairly new to React and I have run into a problem. I need to gather data from an API and then use the data to create Polygons with Google Maps. However, I'm experiencing problems accessing it.
When I log this.state.coordinates:
Console.log result of this.state.coordinates
However, when I try to log this.state.coordinates[0] it shows undefined. My guess is that the order in which the data binds is wrong, but I can't seem to find the solution. Here is my code:
constructor(props) {
super(props);
this.state = {
coordinates: [{}],
loading: 'initial'
};
}
componentDidMount() {
this.setState({
loading: 'true'
})
this.getData()
}
getData = async () => {
let coordinates = []
let res = await axios.get('https://smartcity-parking-api.herokuapp.com/sectors')
const sectors = await res.data.data
sectors.map(async (sector, i) => {
let res = await axios.get(sector.self_links.detail)
const coordinateArray = await res.data.data.coordinates
coordinates[i] = {
latlng: [],
id: res.data.data.sector_data.sector_id
}
coordinateArray.map(coordinate => {
let latlng = {
lat: coordinate.latitude,
lng: coordinate.longitude
}
coordinates[i].latlng.push(latlng)
})
coordinates[i].latlng.push({
lat: coordinateArray[0].latitude,
lng: coordinateArray[0].longitude
})
})
this.setState({
coordinates: coordinates,
loading: 'false'
})
}
render() {
let { coordinates, loading } = this.state
if (loading === 'initial') {
return <h2>Intializing...</h2>;
}
if (loading === 'true') {
return <h2>Loading...</h2>;
}
if (loading === 'false') {
return (
//Google maps here
);
}
I have tried making a loader, but it doesn't seem to be working. Any help would be very appreciated!
Why not set coordinates to null initially in your constructor and then have your conditional be
(loading === 'false' && coordinates)
That may solve your issue.
Change getData function to this.
getData = async () => {
let coordinates = []
let res = await axios.get('https://smartcity-parking-api.herokuapp.com/sectors')
const sectors = res.data.data
const sectorsLinks = await Promise.all(sectors.map(sector => axios.get(sector.self_links.detail)))
sectorsLinks.map((sector, i) => {
const coordinateArray = sector.data.data.coordinates;
coordinates[i] = {
latlng: [],
id: sector.data.data.sector_data.sector_id
}
coordinateArray.map(coordinate => {
let latlng = {
lat: coordinate.latitude,
lng: coordinate.longitude
}
coordinates[i].latlng.push(latlng)
})
coordinates[i].latlng.push({
lat: coordinateArray[0].latitude,
lng: coordinateArray[0].longitude
})
});
console.log(coordinates);
this.setState({
coordinates: coordinates,
loading: 'false'
})
};

Watch Position Ionic 3

Hi guys I need help in how to watch position in google maps with Ionic 3, I would like that upload position in real time in the firebase
In my home.ts I have the following code :
getMyPosition() {
this.geolocation.getCurrentPosition().then((result) => {
this.positionTruck = new google.maps.LatLng(result.coords.latitude, result.coords.longitude);
const mapOptions = {
zoom: 18,
center: this.positionTruck,
disableDefaultUI: true
}
this.map = new google.maps.Map(document.getElementById('map'), mapOptions);
this.truckMarker(this.positionTruck);
let watch = this.geolocation.watchPosition();
watch.subscribe((data) => {
let truck = { latitude: data.coords.latitude, longitude: data.coords.longitude };
this.truckService.updateGeolocation(this.truck.key, truck);
console.log(data.coords)
});
}).catch((error) => {
console.log('Erro ao tentar pegar sua localização ', error);
})
}
And now I have this code in service to update truck.service:
update(key: string, truck: any) {
return new Promise((resolve, reject) => {
this.db.list(this.PATH)
.update(key, (truck))
.then(() => resolve())
.catch((e) => reject())
})
}
this way when I test on the device, the home page giving refresh in page, why ?
Is this form correctly the update position ? help please.
import : import { Geolocation, Geoposition } from '#ionic-native/geolocation';
and declare :
public lat: number = 0;
public lng: number = 0;
and add in your code
let options = {
frequency: 3000,
enableHighAccuracy: true
};
this.watch = this.geolocation.watchPosition(options).filter((p: any) => p.code === undefined).subscribe((position: Geoposition) => {
console.log(position.coords.latitude + ' ++++++++++ ' + position.coords.longitude);
// Run update inside of Angular's zone
this.zone.run(() => {
this.lat = position.coords.latitude;
this.lng = position.coords.longitude;
);
});
});

Categories