navigator.geolocation.getCurrentPosition() is not getting a response from googleapi - reactjs

I am using react to get geolocation on localhost:3000. I have seen another person get the geolocation coordinates on their localhost, but I am unable to do so even with allow location access enabled on Chrome.
I have tried using both the hooks and class syntax in react. I have enabled allow access. I eventually used an ip address api to get a general location, but since the geolocation is supposed to work(at least that is what I have been told) I would at least like to see it work so I can implement it with https in the future. The error log does not even get fired, whereas the first three logs are getting fired when the component is mounted. Here is the code I have tried, I have made it as simple as possible:
const App = props => {
useEffect(() => {
console.log('hello')
console.log(navigator)
console.log(navigator.geolocation)
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition((position) => {
console.log(position)
}, (error) => {
console.log(error)
})
} else {
console.log('error')
}
}, [])
return (
<div>
<h3>Please Login.</h3>
</div>
)
}
export default App
I expect to receive a response from googleapi.
Edit:
I added the error callback and it printed:
message: "Network location provider at 'https://www.googleapis.com/' : No response received."

add the optional error callback to handle the error (if user declines location permission)
navigator.geolocation.getCurrentPosition(success[, error[, [options]])
you are checking only if it is in navigator or not !!!
if user declines location permission then error callback will handle it...
possible options are (reference taken from mdn)
{
enableHighAccuracy: true,
maximumAge : 30000,
timeout : 27000
}

Related

Getting 500 | Internal Server Error when using getServerSideProps only on host (not local)

I know it's an old question but I couldn't resolve this issue. I have a dynamic page using ssr (getServerSidePros). It is working perfectly on my localhost (both of development and production mode), but when I publish it ,I see 500|Internal Server Error. In my console window I see this:
main-50de763069eba4b2.js:1 A client-side exception has occurred, see here for more info: https://nextjs.org/docs/messages/client-side-exception-occurred and I don't get any details.
This is my code
export async function getServerSideProps(context:any) {
var id:number=context.params.id
console.log(context.params.id)
var data:any={}
const getData=async()=>{
const response:any= await axios.get(`http://localhost:99/api/v1/Blog/${id}`)
data=response.data
return data
}
data=await getData();
data=JSON.parse(JSON.stringify(data))
return {
props: {data}, // will be passed to the page component as props
}
}
Some solutions I've tried:
1-adding "main":"index.js"
2-adding axios.defaults.httpsAgent=new https.Agent({rejectUnauthorized:false,})
3-using .json() instead of JSON.stringify()

Can't get the Generic Sensor API to work in a React app

I'm trying to implement the Generic Sensor API in a React app.
https://www.w3.org/TR/generic-sensor/#the-sensor-interface
I keep getting an error when I try to implement any of the sensors in my code.
For example:
var sensor1 = new AmbientLightSensor();
I get the error: Cannot find name: 'AmbientLightSensor'.
I assume that I need an import statement in my code. All of the examples I've found only include LitElement. I've even tried that but still get the unknown error.
What import statements do I need in my typescript code?
What npm packages do I need?
Below is the typescript code I'm using.
I'm getting a typescript error:
/Users/scoleman/dev/current/bigbrother/src/utility/testAccel.ts(14,24):
Cannot find name 'AmbientLightSensor'. TS2304
export const testAccel = async (
databaseName: string,
) => {
const {state} = await navigator.permissions.query({
name: "ambient-light-sensor"
});
if (state !== "granted") {
console.warn("You haven't granted permission to use the light sensor");
return;
}
const sensor = new AmbientLightSensor();
sensor.addEventListener("reading", () => {
console.log(sensor.illuminance);
});
sensor.addEventListener("error", (err: any) => {
console.error(err);
});
sensor.start();
};
I was able to get these api's running using the polyfill at:
https://github.com/kenchris/sensor-polyfills
This would depend entirely on the browser you are using. I don't think FireFox supports it at the moment so I will focus on Chrome.
Firstly, you might need to be serving your site over HTTPS. It seems like this almost varies from permission to permission and also some are available on a localhost URL no matter what.
Secondly, for Chrome, you have to enable the "Generic Sensor Extra Classes" flag in Chrome at the chrome://flags/#enable-generic-sensor-extra-classes page.
Next, you need to make sure that have permission from the user to use the sensor, then you could actually use it. A snippet that would check that is as follows:
(async function(){
const {state} = await navigator.permissions.query({
name: "ambient-light-sensor"
});
if (state !== "granted") {
console.warn("You haven't granted permission to use the light sensor");
return;
}
const sensor = new AmbientLightSensor();
sensor.addEventListener("reading", () => {
console.log(sensor.illuminance);
});
sensor.addEventListener("error", err => {
console.error(err);
});
sensor.start();
}());

Uncaught (in promise) TypeError: Cannot read property 'headers' of undefined

So, I'm attempting to pass a user's ip address in my app, as follows:
pages/Item.js
const Item = props => (
<div>
<SingleItem id={props.query.id} userIP={props.userIP} />
</div>
);
Item.getInitialProps = async ({ req }) => {
const userIP = req.headers['x-real-ip'] || req.connection.remoteAddress
return { userIP }
}
export default withAmp(Item, { hybrid: true });
but get the above mentioned error message (See attached image) when navigating to the page. But if I then do a hard reload of the page the ip details are correctly displayed to the page.
What am I overlooking here and is there a better way to achieve this, for example obtaining the ip address from headers in _document.js?
req will only be available when getInitialProps is called on the server. This is why it works when you do a refresh on the page.
When navigating to the page there is no server render so getInitialProps will be called on the client. Therefore, req will be undefined.
You can wrap the assignment in a condition to check if req is defined to prevent the error:
Item.getInitialProps = async ({ req }) => {
let userIP
if (req) {
userIP = req.headers['x-real-ip'] || req.connection.remoteAddress
}
return { userIP }
}
However, if you want to have userIP available on every page, regardless of whether it's server or client rendered, then you will need to find a way to store it on first load, whichever page that may be.
Perhaps you could store it using context.
There is am example of using context here:
https://github.com/zeit/next.js/tree/master/examples/with-context-api
I hope this helps.

Handle Error when the server is off in react js (TypeError Failed to fetch)

I need to show error in a dialog stating the server has stopped whenever the server crashes or server gets shut down.
I as console log my error in request as below:
export default function request(url, options) {
return fetch(url, options)
.then(checkStatus)
.then(parseJSON).
catch(error => {
console.log("error",error)
throw error;
});
}
the console is :
TypeError Failed to fetch
Can someone help me with this?
you can use navigator in you code in order to check if user is offline nor user can't connect to your WebService like below:
//if there was a problem with server
if(navigator && navigator.onLine) {
throw {
code: 'SERVER_CONNECTION_PROBLEM',
message: 'Server connection failure...'
}
} else { // if there is a problem with internet
throw {
code: 'INTERNET_CONNECTION_ERROR',
message: 'there is a problem with your INTERNET, god damn it...'
}
}
You can check error status e.g. error.status and do
if(error.statusCode === 503){ // or status code which your server send
// do something
}
There is library called react-offline.
which used in detect your network is in work or not.
After proper implementation it should be work, it shows offline page which you created when your network goes down...
link is here : https://openbase.com/js/react-offline/documentation
[Click here for documentation][1]
[1]: https://openbase.com/js/react-offline/documentation
code example :
<Offline
render={() => {
return (
<div>"I take precedence over any function as child component."</div>
);
}}
>
{() => {
return <div>"I will not render."</div>;
}}
</Offline>

Using React to render flash messages from Express

I've searched around a lot but have been unable to find a simple way to get flash messages from Express and render them in React.
I need to access the data on my Express server, but what is the best way of storing this and passing it down to React? I was thinking of passing an object down when the React index.html file is rendered, but I'm not sure how I can access this data, or send the correct data when certain events happen, for example a user enters the wrong password.
I solved the issue.
I simply have a variable in my session called flash which is set to false by default.
In the correct part of the passport flow I redefine this to a string, depending on the error. I have a React action and reducer to get this data and if it's truthy, render it to the screen. When the component unmounts or the site is refreshed I reset it to false.
EDIT: I have found a better solution
1. In the passport middleware set an optional message if something goes wrong.
return done(null, false, { message: 'Email not found' });
2. In the login route send this information as a response.
router.post('/login', (req, res, next) => {
passport.authenticate('local-login', (e, user, info) => {
if(e) return next(e);
if(info) return res.send(info);
req.logIn(user, e => {
if(e) return next(e);
return res.send(user);
});
})(req, res, next);
});
3. Handle the submission and response in a Redux action generator. If the user authenticates, then the message property will be undefined.
const res = await axios.post('/auth/login', { email, password });
dispatch({
type: 'FLASH',
payload: res.data.message
});
4. In the reducer, the state will be either a string or false:
return action.payload || false;
5. Then it's a question of rendering the state to the screen. Another action can be sent when the component unmounts to reset the state.
Hope this helps someone else out there.
expressjs/flash will place an array of flash objects onto res.locals. Per the docs: https://github.com/expressjs/flash#reslocalsflash
res.locals.flash
An array of flash messages of the form:
{
"type": "info",
"message": "message"
}
From my understanding, anything placed on res.locals is available in the global scope. In other words, you should be able to do window.flash which should return an Array of flash objects.
So you would simply loop over the array as you would normally in JavaScript. That is just my guess.
const makeFlashElement = ({type, message}) => {
return (
<div>
<h1>message</h1>
<h2>type</h2>
</div>
)
}
for (message in flash) {
makeFlashElement(message)
// ...
}
Typically you'd return a JSON response which React can easily digest.
See Karl Taylor's comment.

Resources