Retrieving Geolocation of user without index.html - node.js

Hey I'm making a web application that has to track a user location after button is clicked.
I have been using the M.E.R.N stack for this and so far with the tutorials I watched they haven't needed any index.html file just pure JavaScript.
I have implement Google maps on my site without using any HTML files.
This is the code I want to implement
But without having to create a index.html.
How can I add this code to my main.js file without the HTML file?
THIS IS HOW I HAVE GOOGLE MAPS SETUP IN MY LANDING PAGE
import React, { Component } from 'react';
import { Grid, Cell } from 'react-mdl';
import Paper from '#material-ui/core/Paper';
import { Map, GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react';
//THIS IS THE LANDING PAGE.
const mapStyles = {
width: '100%',
height: '100%'
};
export class LandingPage extends Component {
render() {
return (
<Map
google={this.props.google}
zoom={3}
style={mapStyles}
initialCenter={{
lat: 28.871812,
lng: -34.814106
}}
>
</Map>
);
}
}
export default GoogleApiWrapper({
apiKey: 'API-KEY'
})(LandingPage);
THIS IS NAVBAR WITH THE ENTER CODE BUTTON THAT SHOULD REQUEST GEOLOCATION ON CLICK
importS{}
//THIS IS THE NAVIGATION BAR PAGE.
export default class NavBar extends React.Component {
constructor(props) {
super(props);
this.toggleNavbar = this.toggleNavbar.bind(this);
this.state = {
collapsed: true
};
}
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
};
toggleNavbar() {
this.setState({
collapsed: !this.state.collapsed
});
}
render() {
return (
<div>
<Navbar style={{background: '#948E99', flex: 1,
background: '-webkit-linear-gradient(to right, #2E1437, #948E99)',
background: 'linear-gradient(to right, #2E1437, #948E99)'}} dark>
<NavbarToggler color="white" onClick={this.toggleNavbar} className="mr-2" />
<Button style={{color: 'white'}} href="/" className="mrauto">DigitalDollar</Button>
<Button style={{color: 'white'}} onClick={this.handleClickOpen} className="mr-auto">Enter Code</Button>
<Dialog
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Enter Code</DialogTitle>
<DialogContent>
<DialogContentText>
Thank you for participating in the DigitalDollar global run! By entering this code we will
add your location to our map, please enter your magnificint code here. Thank you for your
participation.
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="Code"
label="Enter Code"
type="Code"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
Cancel
</Button>
<Button onClick={this.handleClose} color="primary">
Subscribe
</Button>
</DialogActions>
</Dialog>
<Collapse isOpen={!this.state.collapsed} navbar>
<Nav navbar>
<NavItem>
<NavLink href="/">Home</NavLink>
</NavItem>
<NavItem>
<NavLink href="/about">About</NavLink>
</NavItem>
<NavItem>
<NavLink href="https://github.com/CH-SYR3" rel="noopener noreferrer" target="_blank">GitHub</NavLink>
</NavItem>
<NavItem>
<NavLink href="https://www.paypal.com/us/home" rel="noopener noreferrer" target="_blank">Buy Me A Coffee?</NavLink>
</NavItem>
</Nav>
</Collapse>
</Navbar>
<div>
<Navbar color="light" light expand="md">
<Nav className="NavTabs" navbar>
<NavItem>
<NavLink href="/">Map</NavLink>
</NavItem>
<NavItem>
<NavLink href="/time">Time</NavLink>
</NavItem>
<NavItem>
<NavLink href="/hello">Hello</NavLink>
</NavItem>
</Nav>
</Navbar>
</div>
</div>
);
}

It's not a file, just an html5 standard that works in browsers. In the link you provide, the navigation language is in the script tag. If you wrap the navigator.geolocation method in a function getUserLoc() that does little more than setState with the coordinates on click, you will be able to update the map's position by setting state. You'd set the initial state in LandingPage's constructor, then pass `getUserLoc() function to your NavBar component where it can be run with this.props.getUserLoc().
const mapStyles = {
width: '100%',
height: '100%'
};
export class LandingPage extends Component {
constructor(props) {
super(props)
this.state={
lat: 28.871812,
lng: -34.814106
}
this.getUserLoc = this.getUserLoc.bind(this)
}
getUserLoc() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
this.setState({
userLat: pos.lat,
userLng: pos.lng
})
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
render() {
return(
<div>
<Map
google={this.props.google}
zoom={3}
style={mapStyles}
initialCenter={{
lat: this.state.userLat,
lng: this.state.userLng
}}
>
</Map>
<NavBar getUserLoc={this.getUserLoc}/>
</div>
)
}
}

Related

Wrapping code inside styled component in React.js yields unexpected results on show password button click

App.js:
import './App.css';
import React, { Component } from 'react'
import Register from './Components/Register';
import Greet from './Components/Greet';
class App extends Component {
constructor(props) {
super(props)
this.state = {
isRegistered: false,
name: null,
email: null,
password: null,
showPass:false,
}
}
registerHandler=(e) => {
e.preventDefault();
const name = e.target.name.value;
const email = e.target.email.value;
const password = e.target.password.value;
this.setState({ isRegistered: true,name,email,password});
}
showPassHandler=()=>{
this.setState({showPass:!(this.state.showPass)});
}
render() {
return (
<div>
{this.state.isRegistered?<Greet name={this.state.name} email={this.state.email}/>:<Register submit={this.registerHandler} click ={this.showPassHandler} showPass={this.state.showPass}/>}
</div>
)
}
}
export default App;
/////////////////////////////////////////////////////////////
Register.js:
import React,{useState} from 'react'
import Styled from "styled-components";
export default function Register(props) {
const btnStyle={
backgroundColor:"red",
color:"white",
}
// const savePassword=(val)=>{
// show=val.target.value;
// val.target.value=show;
// inputRef.current.focus();
// val.target.focus();
// console.log(show);
// setPass(show);
// }
// console.log(show);
let btnText;
const btnClasses = ["btn","m-1","mt-2"];
if(props.showPass===true)
{
btnStyle.backgroundColor = "green";
btnText="hide password";
btnClasses.push("btn-primary");
}
else{
btnText="show password";
btnClasses.push("btn-danger");
}
const StyledButton = Styled.button
`
background-color: ${(props)=>props.bgColor};
color: white;
display:${(props)=>props.flag==="1"?"inline-block":"block"};
width:${(props)=>props.flag==="1"?"45%":"100%"};
margin:5px;
`
const StyledRegisterContainer = Styled.div`
width:600px;
&:hover {box-shadow:0px 0px 5px grey};
#media (min-width:0px) and (max-width:600px) {
width:300px;
};
`;
//register-container=> was class inside most outer div
return (
<StyledRegisterContainer className='container card mt-4 p-3 '>
<h1 className='text-center'>
Registration Form
</h1>
<form onSubmit={props.submit}>
<div className='form-group'>
<label className='control-label' htmlFor='name'>Name:</label>
<input type='text' name='name' className='form-control'/>
</div>
<div className='form-group'>
<label className='control-label' htmlFor='email'>Email:</label>
<input type='email' name='email' className='form-control'/>
</div>
<div className='form-group'>
<label className='control-label' htmlFor='password'>password:</label>
<input type={props.showPass?"text":"password"} name='password' required className='form-control' />
</div>
<button type='submit' className='btn btn-primary mt-2 m-1'>
Register
</button>
<button type ="button" className={btnClasses.join(" ")} onClick={props.click}>
{btnText}
</button>
<br/>
<StyledButton flag="1" bgColor="orange">Login</StyledButton>
<StyledButton flag="1" bgColor="blue">Login</StyledButton>
<StyledButton flag="0" bgColor="brown">Login</StyledButton>
</form>
</StyledRegisterContainer>
)
}
//style = {btnStyle}//it was inside button =>show password
inside Register.js file everything was working perfect but when I wrapped the code inside StyledRegisterContainer(a styled component) the functionality of show password button is disturbed and the moment I click on show password button the text from input box disapears.
I want my code to work even after wrapping it inside the above mentioned styled component.
I am not familiar with styled-components, but according to their documentation, it seems like you're importing Styled instead of styled
import styled from 'styled-components';
https://styled-components.com/docs/basics#installation

TypeError: changeChecked is not a function

I am trying to pass changeChecked as prop from parent to this child component to capture the input element id but I am getting this error. I have mentioned the child component and parent component. Please help me to solve this error.
Child Component
import { useState, useEffect } from 'react';
const CheckBox = ({ changeChecked, section }) => {
return (
<>
{section.options.map((option, optionIdx) => (
<div key={option.value} className="flex items-center">
<input
id={`filter-${section.id}-${optionIdx}`}
name={`${section.id}[]`}
defaultValue={option.value}
type="checkbox"
defaultChecked={option.checked}
onChange={() => changeChecked(option.id)}
className="h-4 w-4 border-gray-300 rounded text-indigo-600 focus:ring-indigo-500"
/>
<label
htmlFor={`filter-${section.id}-${optionIdx}`}
className="ml-3 lg:text-sm min-w-0 flex-1 text-gray-500"
>
{option.label}
</label>
</div>
))}
</>
)
}
export default CheckBox;
Parent Component
import CheckBox from "../pages/collections/checkbox"
export default function App() {
const filters = [
{
id: 'brand',
name: 'Brands',
options: [
{ value: 'Casio', label: 'Casio', checked: false },
{ value: 'Yamaha', label: 'Yamaha', checked: false },
],
},
]
const onChangeChecked = (id)=>{
console.log(id)
}
return (
<div className="App">
{filters.map((section) => (
<CheckBox section={section} changeChecked={onChangeChecked} />
))}
</div>
);
}
This is a full example of passing a function as a prop.
Don't forget to pass the props when you are using the Input component, or you will get the same error as above.
export default function App() {
const onHandleClick = (e)=>{
console.log(e.target.value)
}
return (
<div className="App">
<Input onHandleClick={onHandleClick}/>
</div>
);
}
function Input ({ onHandleClick }) {
return <input onChange={(e) => onHandleClick(e)}/>
}

"Expected `onClick` listener to be a function, instead got a value of `string` type (ReactJS/MaterialUI)

I create a login button that onClick logs the user in and then the generated information is stored in the local storage, but I keep getting an "Expected onClick listener to be a function, instead got a value of string type. I am using reactJS to do so.
// Global Navigation Bar
import { connect } from "react-redux";
import React, { Component } from "react";
import cognitoUtils from "lib/cognitoUtils";
import "assets/css/Base.css";
import Avatar from "#material-ui/core/Avatar";
import Tooltip from "#material-ui/core/Tooltip";
import AccountCircleOutlinedIcon from "#material-ui/icons/AccountCircleOutlined";
import AccountCircleIcon from "#material-ui/icons/AccountCircle";
const mapStateToProps = state => {
return { session: state.session };
};
class SignInOut extends Component {
onSignOut = e => {
e.preventDefault();
cognitoUtils.signOutCognitoSession();
};
state = {
on: true
};
toggle = () => {
this.setState({
on: !this.state.on
});
};
render() {
return (
<div>
<button className="profile_button" onClick={this.toggle}>
{this.state.on && (
<div>
{this.props.session.isLoggedIn ? (
<div>
<a
className="Home-link"
href="/home"
onClick={this.onSignOut}
>
<Tooltip title="Profile">
<Avatar className="profile_icon">
<AccountCircleIcon className="profile_icon_in" />
</Avatar>
</Tooltip>
</a>
</div>
) : (
<div>
<a
className="Home-link"
href={cognitoUtils.getCognitoSignInUri()}
onClick="/home"
>
<Tooltip title="Profile">
<Avatar className="profile_icon">
<AccountCircleOutlinedIcon className="profile_icon" />
</Avatar>
</Tooltip>
</a>
</div>
)}
</div>
)}
</button>
</div>
);
}
}
export default connect(mapStateToProps)(SignInOut);
Because you are passing String type to onClick
onClick="/home"
You need to pass a function as stated in the error. something like you did before
onClick={this.onSignOut}

Scroll to particular component in Preact

i am working on preact app and i have different components imported in a single page, i want to click on button in header and scroll to particular component.
this is my parent component
<div class={style.root}>
<Header />
<Landing />
<HowItWorks />
<BrowserCatalogue />
<ContactUs />
<Footer />
</div>
and in my header i have 3 buttons
<div class={styles.headerItems}>
<span style={styles.pointer}>Working</span>
<span style={styles.pointer}>Catalogue</span>
<span style={styles.pointer}>Contact</span>
</div>
</div>
like when i click on working my page should scroll to HowItWorks component.any help?
Let me help you friend. You should introduce refs in your parent component.
We will wrap each section in a div and give it a ref prop.
Here is sandbox for your reference: https://codesandbox.io/s/navbar-click-scroll-into-section-us8y7
Parent Component
import React from "react";
import ReactDOM from "react-dom";
import Header from "./Header";
import HowItWorks from "./HowItWorks";
import BrowserCatalogue from "./BrowserCatalogue";
import "./styles.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
selected: null
};
}
//refs
howItWorks = React.createRef();
browserCatalogue = React.createRef();
changeSelection = index => {
this.setState({
selected: index
});
};
componentDidUpdate() {
this.scrollToSection(this.state.selected);
}
scrollToSection = index => {
let refs = [this.howItWorks, this.browserCatalogue];
if (refs[index].current) {
refs[index].current.scrollIntoView({
behavior: "smooth",
block: "nearest"
});
}
};
render() {
return (
<div className="App">
<div>
<Header changeSelection={this.changeSelection} />
</div>
<div ref={this.howItWorks}>
<HowItWorks />
</div>
<div ref={this.browserCatalogue}>
<BrowserCatalogue />
</div>
</div>
);
}
}
Header
const Header = (props) => {
const { changeSelection } = props;
return (
<div style={{ background: "green" }}>
<span onClick={() => changeSelection(0)}>Working</span>{" "}
<span onClick={() => changeSelection(1)}>Catalogue</span>{" "}
<span>Contact</span>
</div>
);
}
Workflow:
Each component gets a ref, and we keep that in memory for when we
need to scroll.
Header, we defined a handler in parent called changeSelection()
and we pass it as prop. It takes an index and we use that index to
update the parent state.
Each link, "Working", "Catalogue", etc, will correspond to an index
that matches with a ref in our parent, so setting up an onClick() handler for each span will allow us to pass in that index to changeSelection()
parent state is updated, triggers componentDidUpdate(), in there
we run scrollToSection() which you guessed it takes in an index (stored in our state as "selected"). Create an array of our refs, and simply use the matching index to locate that ref and scroll to that component.

Blaze LoginButtons Template Rendered in React - Login Only Works on Homepage

So I am using Meteor/React, but I used Blaze's login template for its convenience. It works great on the homepage, but when I try to login from any other page on the site, the page reloads and the login appears to have been unsuccessful.
This is my implementation.
AccountsUI.jsx
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
export class AccountsUI extends React.Component {
componentDidMount(){
this.view = Blaze.render(Template.loginButtons, this.refs.loginContainer);
}
componentWillUnmount(){
Blaze.remove(this.view);
}
render(){
return(
<span ref="loginContainer" />
)
}
}
mainLayout.jsx
<div className="container-fluid">
<a className="navbar-btn pull-left panel-body"><b>FAQ</b></a>
<a className="navbar-btn pull-right panel-body"><b>Category</b></a>
<a className="navbar-btn pull-right panel-body"><b>Notifications</b></a>
<a className="navbar-btn pull-right panel-body"><b><AccountsUI /></b></a>
</div>
</div>
Why would this work only on certain pages?
Blaze
Your code looks ok, are you importing all components correctly?
Try: https://atmospherejs.com/gadicc/blaze-react-component
and do:
import Blaze from 'meteor/gadicc:blaze-react-component';
....
<a className="navbar-btn pull-right panel-body"><b><Blaze template="loginButtons" /></b></a>
....
Without trying to change your choice of tools too much, I have been exploring React, Meteor and Authentication for a little while, often getting stuck in state management and other dark holes. Below is a overview of some options:
React Accounts-UI package
Personally as a quick tool I am a big fan of the React Accounts-UI package https://atmospherejs.com/std/accounts-ui
It's easy to implement and has many React specific config options.
Check out 'Create your own styled version' to implement in Navbar at https://github.com/studiointeract/accounts-ui/blob/master/README.md
React with Kadira FlowRouter and ReactLayout
For something within the Navbar, here is a stab with flow router.
From the Meteor Guide User/Authentication section:
While a router is optional and the basic functionality will work without it, it’s also a good idea to pick a router integration:
For Navbar login (Not React Accounts-UI).
You need Flowrouter and Reactlayout
Routes
We create 2 route groups which allow us to build auth logic into Flow router easily:
const publicRoutes = FlowRouter.group( { name: 'public' } );
publicRoutes.route( '/login', {
name: 'login',
action() {
ReactLayout.render( App, {
yield: <Login /> }
);
}
}
);
const authenticatedRoutes = FlowRouter.group( { name: 'authenticated' } );
authenticatedRoutes.route( '/hidden', {
name: 'hidden',
action() {
ReactLayout.render( App, {
yield: <Hidden /> }
);
}
}
);
App:
You can modify this to suit your own setup. The approach here is to grab the reactmeteordata mixing which allows us to test if the user is logged or logging in. The isPublic function allows us to test if the user should be allowed on the current route. The rest should be self explanatory.
App = React.createClass({
mixins: [ ReactMeteorData ],
getMeteorData() {
return {
loggingIn: Meteor.loggingIn(),
hasUser: !!Meteor.user(),
isPublic( route ) {
let publicRoutes = [
'login'
];
return publicRoutes.indexOf( route ) > -1;
},
canView() {
return this.isPublic( FlowRouter.current().route.name ) || !!Meteor.user();
}
};
},
loading() {
return <div className="loading"></div>;
},
getView() {
return this.data.canView() ? this.props.yield : <Login />;
},
render() {
return <div className="app-root">
<AppHeader hasUser={this.data.hasUser} />
<div className="container">
{this.data.loggingIn ? this.loading() : this.getView()}
</div>
</div>;
}
}
);
Header:
Nothing cosmic, we change the brandLink depending on user state. We then check hasUser (passed as a prop from the App component) to change which nav component to display.
AppHeader = React.createClass({
mixins: [ ReactMeteorData ],
getMeteorData() {
return { brandLink: !!Meteor.user() ? '/hidden' : '/login' }; },
render() {
return ( <nav className="navbar navbar-default" role="navigation">
<div className="container">
<div className="navbar-header">
<button type="button" className="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse"><span className="sr-only">Toggle navigation</span><span className="icon-bar"></span> <span className="icon-bar"></span><span className="icon-bar"></span>
</button>
<a className="navbar-brand" href={this.data.brandLink}>AuthExample</a>
</div>
{this.props.hasUser ? <AuthenticatedNavigation /> : <PublicNavigation />}
</div>
</nav> );
}
});
AuthenticatedNavigation component :
AuthenticatedNavigation = React.createClass({
currentUserEmail() {
return Meteor.user().emails[0].address;
},
logout( event ) {
event.preventDefault();
return Meteor.logout( () =>
FlowRouter.go( '/login' ) );
},
render() {
return <div id="navbar-collapse" className="collapse navbar-collapse">
<ul className="nav navbar-nav">
<li className={FlowHelpers.currentRoute( 'hidden' )}>Hidden
</li>
</ul>
<ul className="nav navbar-nav navbar-right">
<li className="dropdown">
<a href="#" className="user-profile-toggle dropdown-toggle clearfix" data-toggle="dropdown">{this.currentUserEmail()} <span className="caret"></span>
</a>
<ul className="dropdown-menu" role="menu">
<li>Account Preferences</li>
<li className="logout" onClick={this.logout}>Logout</li>
</ul>
</li>
</ul>
</div>;
}
});
PublicNavigation Component:
PublicNavigation = React.createClass({
render() {
return (
<div id="navbar-collapse" className="collapse navbar-collapse">
<ul className="nav navbar-nav navbar-right">
<li className={FlowHelpers.currentRoute( 'login' )}>
<a href={FlowHelpers.pathFor( 'login' )}>Login</a>
</li>
</ul>
</div> );
}
}
);
Look at https://themeteorchef.com/snippets/authentication-with-react-and-flow-router/ for more details.

Resources