Netflify Serverless Function JSON parse error Sendgrid API - json

My contact form is not sending the frontend user to my thank you page neither is it sending any information to me via the Sendgrid APi. The issue comes from the fact that I'm not sure how to turn the JSON object into a string and then straight back to an Object..... Or as you can see I have a hard time even framing my question. The goal would be to send the information to my email account using Sendgrid API.
The form is live here:
https://www.metsanotus.fi/yhteydenotto
The code is based 99% off these two tutorials:
https://oliverschmidt.dev/blog/adding-a-contact-form-to-a-static-site-with-netlify-functions/
https://dev.to/char_bone/using-netlify-lambda-functions-to-send-emails-from-a-gatsbyjs-site-3pnb
The code for the contact-page:
https://gist.github.com/otsolap/f05cd4e3a1a08794f61a6d5730abc695
import React, { useState } from "react";
import { graphql } from "gatsby"
import { RiSendPlane2Line } from "react-icons/ri";
import Layout from "../components/layout"
import SEO from "../components/seo"
export const pageQuery = graphql`
query ContactQuery($id: String!){
markdownRemark(id: { eq: $id }) {
id
html
excerpt(pruneLength: 140)
frontmatter {
title
}
}
site {
siteMetadata {
title
}
}
}
`
const Contact = ({ data }) => {
const { markdownRemark, site } = data // data.markdownRemark holds your post data
const { frontmatter, html } = markdownRemark
// input type hidden on netlifytä varten, jotta netlify tietää mikä lomake kyseessä.
// contact on meidän lomake, niin kaikki viestit löytyy contact-lomakkeen alta.
// honeypot=bot-field on botteja varten.
// p hidden pitää kohdan piilossa, mutta console.logilla sen löytää. ;-)
const [formState, setFormState] = useState({
name: '',
email: '',
phone: '',
subject: '',
message: '',
})
const handleChange = (e) => {
setFormState({
...formState,
[e.target.name]: e.target.value,
});
}
const handleSendEmail = async (event) => {
event.preventDefault();
try {
const response = await fetch("/.netlify/functions/contact-form-email", {
method: "POST",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formState),
})
if (!response.ok) {
//EI 200 response
return
}
//all OK
} catch (event) {
//error
}
}
return (
<Layout className="contact-page">
<SEO
title={frontmatter.title}
description={frontmatter.title + " " + site.siteMetadata.title}
/>
<div className="wrapper">
<h1>{frontmatter.title}</h1>
<div className="description" dangerouslySetInnerHTML={{ __html: html }} />
<form className="contact-form"
action="/kiitos"
name="contact"
method="POST"
data-netlify="true"
value="contact"
data-netlify-honeypot="bot-field"
onSubmit={handleSendEmail}
>
<input type="hidden" name="form-name" value="contact" />
<p hidden><input name="bot-field" /></p>
<p>
<label><input
required
placeholder="Nimi *"
type="text"
name="name"
onChange={handleChange}
/>
</label>
</p>
<p>
<label><input required
placeholder="Sähköposti *"
type="email"
name="email"
onChange={handleChange}
/>
</label>
</p>
<p>
<label><input required
placeholder="Puhelin *"
type="number"
name="phone"
onChange={handleChange}
/>
</label>
</p>
<p>
<label><input placeholder="Aihe"
type="text"
name="subject"
onChange={handleChange}
/>
</label>
</p>
<p>
<label><textarea
placeholder="Viesti"
name="message"
onChange={handleChange}
></textarea></label>
</p>
<p className="text-align-center">
<button className="button"
type="submit">
Lähetä<span className="icon -right"><RiSendPlane2Line />
</span>
</button>
</p>
</form>
</div>
</Layout>
)
}
export default Contact
The code for the serverless function:
https://gist.github.com/otsolap/e157b136aee040281f20ba87131014eb
require('dotenv').config();
const sgMail = require('#sendgrid/mail')
const {
SENDGRID_API_KEY,
METSAN_OTUS_NAME,
METSAN_OTUS_ADDRESS }
= process.env
sgMail.setApiKey(SENDGRID_API_KEY)
exports.handler = async (event, context, callback) => {
const payload = JSON.parse(event.body)
const { email, subject, message } = payload
const msg = {
to: METSAN_OTUS_ADDRESS,
name: METSAN_OTUS_NAME,
from: email,
subject: subject ? subject : 'Yhteydenotto lomakkeesta',
text: message,
};
try {
await sgMail.send(msg)
return {
statusCode: 200,
body: "Viesti lähetetty"
}
} catch (e) {
return {
body: e.message,
statusCode: 500,
}
}
};
When I keep the JSON.parse(body.event) this is the error it displays:
https://gist.github.com/otsolap/79830f6cf1e9b247c63c1f3f49c5286b
SyntaxError: Unexpected token u in JSON at position 0
If I change the line 13 of serverless-function.js from JSON.parse(event.body) to (for example) JSON.stringify(event.body) the error becomes this:
TypeError: Cannot destructure property 'email' of 'payload' as it is undefined.
So I guess my question is how should I formulate my serverless function so that the React object from UseState can become readable for my function?

Related

Sending Enum Value with spaces using Prisma and MySQL

I am going to try my best to explain this issue...
I am working on building a request tracker App in NextJS using Prisma as the ORM and MySQL as the Database.
I am wanting to be able to send the Status to the Database without having to add the Underscores into it.
Is this possible?
Here is my Prisma Schema
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "darwin"]
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model requests {
id Int #id #default(autoincrement())
project_id String #db.VarChar(255)
request_type requests_request_type?
name String? #db.VarChar(255)
account_name String? #db.VarChar(255)
legacy_org requests_legacy_org?
total_hours_spent Int?
status requests_status?
updated_on DateTime? #default(now()) #db.DateTime(0)
comment String? #db.Text
}
enum requests_request_type {
Rem
Add_on #map("Add on")
New_Logo #map("New Logo")
Migration
}
enum requests_legacy_org {
CSC
ES
}
enum requests_status {
To_be_Started #map("To be Started")
Work_in_Progress #map("Work in Progress")
Awaiting_Customer_Confirmation #map("Awaiting Customer Confirmation")
Completed
}
This function creates the entry in the Database
import type {NextApiRequest, NextApiResponse} from 'next';
import prisma from '../../../../lib/prisma';
export default async function handle(
req: NextApiRequest,
res: NextApiResponse
) {
const {name, projectID, accountName, status, requestType, totalHours} =
req.body;
const result = await prisma.requests.create({
data: {
name: name,
project_id: projectID,
account_name: accountName,
status: status,
request_type: requestType,
total_hours_spent: totalHours,
},
});
res.json(result);
}
This is my page to add the request
import React, {useState} from 'react';
import Router from 'next/router';
const AddRequest = () => {
const [name, setName] = useState('');
const [projectID, setProjectID] = useState('');
const [accountName, setAccountName] = useState('');
const [status, setStatus] = useState('To_be_Started');
const [requestType, setRequestType] = useState('');
const [totalHours, setTotalHours] = useState(0);
const submitData = async (e: React.SyntheticEvent) => {
e.preventDefault();
try {
const data = {
name,
projectID,
accountName,
status,
requestType,
totalHours,
};
await fetch('/api/requests/add', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data),
});
await Router.push('/requests');
} catch (error) {
console.log(error);
}
};
return (
<>
<div className="container flex-auto">
<form onSubmit={submitData}>
<h1 className="text-3xl">New Request</h1>
<div className="text-center grid grid-cols-2 gap-3">
<input
className="border border-black"
type="text"
placeholder="Name"
value={name}
onChange={(e) => {
setName(e.target.value);
}}
/>
<input
className="border border-black"
type="text"
placeholder="Project ID"
onChange={(e) => {
setProjectID(e.target.value);
}}
value={projectID}
/>
<input
className="border border-black"
type="text"
placeholder="Account Name"
onChange={(e) => {
setAccountName(e.target.value);
}}
value={accountName}
/>
<input
className="border border-black"
type="text"
placeholder="Request Type"
onChange={(e) => {
setRequestType(e.target.value);
}}
value={requestType}
/>
<button
className="border border-black bg-red-100"
disabled={!name || !projectID}
type="submit">
Create
</button>
</div>
</form>
</div>
</>
);
};
export default AddRequest;
Enum Identifiers having embedded spaces are not supported yet.
We have a Feature Request for adding support to allow arbitrary enum values here: #4954. Please feel free to add a comment to the Feature Request so that we can prioritise it.
For this enum:
enum requests_status {
To_be_Started #map("To be Started")
Work_in_Progress #map("Work in Progress")
Awaiting_Customer_Confirmation #map("Awaiting Customer Confirmation")
Completed
}
The generated types for now would be:
export const requests_status: {
To_be_Started: 'To_be_Started',
Work_in_Progress: 'Work_in_Progress',
Awaiting_Customer_Confirmation: 'Awaiting_Customer_Confirmation',
Completed: 'Completed'
};
The #map only applies to the schema and right at query time.

Integrate Ant Design Form with Modal

I am pretty new to React and JS, and I am currently trying to create a component to integrate the antd form with modal so that I could utilize the form functionalities such as "validation".
Here is my code:
The function to post the request:
import baseUrl from "./baseUrl";
export async function _postSchoolRollOutRequest(schoolRollOutRequestForm) {
try {
const response = await fetch(
`${baseUrl}/feedbacks/request/schoolRollOutRequest`,
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(schoolRollOutRequestForm),
}
);
const data = await response.json();
console.log("Post school roll out form success!");
return data;
} catch (e) {
console.log("Post school roll out form failed!", e);
}
}
The component of integrating the form with modal:
import React, { useState } from "react";
import { Modal, Button, Form, Input, Radio } from "antd";
import { _postSchoolRollOutRequest } from "../../api/feedbacksApi";
import "./PopUp.scss";
export default (props) => {
const FormItem = Form.Item;
const [visible, setVisible] = useState(false);
const showModal = () => {
setVisible(true);
};
const handleOk = (schoolRollOutRequestForm) => {
_postSchoolRollOutRequest(schoolRollOutRequestForm);
setVisible(false);
};
const handleCancel = () => {
setVisible(false);
};
return (
<>
<Button type="primary" onClick={showModal}>
Roll-out My School!
</Button>
<Modal
destroyOnClose={true}
visible={visible}
title="Roll-out Request"
onCancel={handleCancel}
footer={[
<Button
block
key="submit"
type="primary"
onClick={(feedbackSubmission) =>
handleOk({
shoolName: feedbackSubmission.shoolName,
otherFeedback: feedbackSubmission.otherFeedback,
contact: feedbackSubmission.contact,
})
}
>
Roll-out My School!
</Button>,
]}
width={400}
>
<div className={"modal-body center"}>
<Form layout="vertical">
<Form.Item
label="Schools Name"
name="schoolName"
rules={[{ required: true }]}
>
{<Input type="text" label="schoolName" placeholder="UT Austin" />}
</Form.Item>
<FormItem
label="Any other requirements/feedback (optional)"
name="otherFeedback"
>
{<Input type="textarea" placeholder="abcd..." />}
</FormItem>
<FormItem label="How do we contact you? (optional)" name="contact">
{<Input type="text" placeholder="abcd#email.com" />}
</FormItem>
</Form>
</div>
</Modal>
</>
);
};
However, I encountered two problems that really confused me:
I think the button at the footer does not trigger the form's onFinish so that the form's validation does not work, I am wondering could I get any clue about the best practice for my situation?
I tried to fake a json for "handleOk" then later "_postSchoolRollOutRequest", but it seems like my backend get a request with an empty payload, could I get any insights about this problem as well?
Code Sandbox:
https://codesandbox.io/s/antdesignmodalform-stackoverflow-3yv4h?file=/index.js:920-3529
Firstly submit button should be inside form tag. If it is outside form tag then you need to make use of form attribute to trigger it.
In your case modal is always outside the form, so you have to link submit button with the form.
Here is how you can achieve it using ANT design.
Action Handler Code (if you are using redux then modify callback part as per your requirement)
export async function _postSchoolRollOutRequest(
schoolRollOutRequestForm,
callback
) {
const baseUrl = "http://testing.com";
console.log("form values", schoolRollOutRequestForm);
try {
const response = await fetch(
`${baseUrl}/feedbacks/request/schoolRollOutRequest`,
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(schoolRollOutRequestForm)
}
);
const data = await response.json();
console.log("Post school roll out form success!");
callback(response.status, data);
} catch (e) {
callback(e.status);
console.log("Post school roll out form failed!", e);
}
}
Form component
const FormModal = () => {
const [form] = Form.useForm();
const [visible, setVisible] = useState(false);
const [postData, setPostData] = useState({
loading: false,
error: false,
data: []
});
const onSubmit = (values) => {
setPostData({ ...postData, loading: true, error: false });
_postSchoolRollOutRequest(values, (status, data) => {
if (status === 200) {
form.resetFields();
setPostData({ ...postData, loading: false, data: data });
} else {
setPostData({
...postData,
loading: false,
error: true,
data: "Post school roll out form failed!"
});
}
});
};
return (
<>
<Button
type="primary"
onClick={() => {
setVisible(true);
}}
>
click to open form
</Button>
<Modal
visible={visible}
title="Post data"
okText="Submit"
cancelText="Cancel"
onCancel={() => {
setVisible(false);
}}
footer={[
<Button key="cancel" onClick={() => setVisible(false)}>
Cancel
</Button>,
<Button
key="submit"
type="primary"
loading={postData.loading}
onClick={() => {
form
.validateFields()
.then((values) => {
onSubmit(values);
})
.catch((info) => {
console.log("Validate Failed:", info);
});
}}
>
Submit
</Button>
]}
>
<Form
form={form}
layout="vertical"
name="form_in_modal"
initialValues={{
modifier: "public"
}}
>
<Form.Item
label="Schools Name"
name="schoolName"
rules={[
{
required: true,
message: ""
}
]}
>
<Input />
</Form.Item>
<Form.Item
label="Any other requirements/feedback (optional)"
name="otherFeedback"
>
<Input type="textarea" />
</Form.Item>
<Form.Item label="How do we contact you? (optional)" name="contact">
<Input />
</Form.Item>
{postData.error && (
<>
<br />
<span style={{ color: "red" }}>{postData.data}</span>
</>
)}
</Form>
</Modal>
</>
);
};

How do i send data from 2 inputs into one json server object?

I am trying to create a simple login sistem using react and json server (on localhost port).
I have 2 inputs, one for name the other for password.
My problem is that when i try to submit those inputs, on the server side both name and password appear with the values from the password.
class AddAcc extends Component {
constructor(props) {
super(props);
this.input = null;
this.pushAcc = this.pushAcc.bind(this)
}
async pushAcc() {
try {
await Axios
.post(
`${BASE_URL}users`,
{
name: this.input.value,
password: this.input.value,
},
{
'Content-Type': 'aplication/json'
}
)
this.props.newAcc(this.input.value);
} catch(e) {
}
}
render() {
return(
<div>
<p>
<input
ref={name => this.input = name} />
</p>
<div>
<h3>Enter Password</h3>
</div>
<p>
<input
ref={pass => this.input = pass} />
</p>
<button onClick = {this.pushAcc} type="submit"> SUBMIT </button>
</div>
)
}
}
export default AddAcc;
Because you are using same ref this.input for both name and password.
Change for password
<input ref={pass => this.passwordInput = pass} />
This is simply because you are using same name for name ans pass. So simple solution is this,
<input ref={name => this.inputName = name} />
<input ref={pass => this.inputPass = pass} />
Then do this,
await Axios
.post(
`${BASE_URL}users`,
{
name: this.inputName.value,
password: this.inputPass.value,
},
{
'Content-Type': 'aplication/json'
}
)

How to login validation using my api in React Js

React JS
I'm new to react js
In my api there is username and password. If the user login, have to validate from my json value
handleSubmit(e) {
fetch('https://randomuser.me/api?results=1')
.then((response) => {
return response.json()
.then((json) => {
if (response.ok) {
return Promise.resolve(json)
}
return Promise.reject(json)
})
})
alert(json) not working to check the result.
How can i fetch the username and password in the response?
And how to take this next page if the user was logged in successfully ?
My full Code
App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';
const ReactCSSTG = CSSTransitionGroup;
class App extends Component {
constructor(props) {
super(props);
this.state = {
isVisible: true
}
// Bindings
this.handleSubmit = this.handleSubmit.bind(this);
this.handleRemount = this.handleRemount.bind(this);
}
handleSubmit(e) {
alert("dsa");
fetch('https://randomuser.me/api?results=1')
.then((response) => {
return response.json()
.then((json) => {
if (response.ok) {
return Promise.resolve(json)
}
return Promise.reject(json)
})
})
}
handleRemount(e) {
this.setState({
isVisible: true
}, function () {
console.log(this.state.isVisible)
});
e.preventDefault();
}
render() {
// const for React CSS transition declaration
let component = this.state.isVisible ? <Modal onSubmit={this.handleSubmit} key='modal' /> : <ModalBack onClick={this.handleRemount} key='bringitback' />;
return <ReactCSSTG transitionName="animation" transitionAppear={true} transitionAppearTimeout={500} transitionEnterTimeout={500} transitionLeaveTimeout={300}>
{component}
</ReactCSSTG>
}
}
// Modal
class Modal extends React.Component {
render() {
return <div className='Modal'>
<Logo />
<form onSubmit={this.props.onSubmit}>
<Input type='text' name='username' placeholder='username' />
<Input type='password' name='password' placeholder='password' />
<button> Sign In</button>
</form>
<a href='#'>Lost your password ?</a>
</div>
}
}
// Generic input field
class Input extends React.Component {
render() {
return <div className='Input'>
<input type={this.props.type} name={this.props.name} placeholder={this.props.placeholder} required />
<label htmlFor={this.props.name}></label>
</div>
}
}
// Fake logo
class Logo extends React.Component {
render() {
return <div className="logo">
<i><img src={logo} className="App-logo" alt="logo" /></i>
<span> Test </span>
</div>
}
}
// Button to brind the modal back
class ModalBack extends React.Component {
render() {
return (
<button className="bringitback" onClick={this.props.onClick} key={this.props.className}>Back to login page!</button>
);
}
}
export default App;
Thanks in Advance!
If you just want to catch data for now this will do the trick
fetch('https://randomuser.me/api?results=1')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
fetch('https://randomuser.me/api?results=1')
.then((response) => {
// check for status code from service if success
// set response in state such as login success
this.route.navigate(['/']);
})
.catch(error =>{
console.log(error);
});
})
Taking user to next page. Use react router for achieving this.
Step 1: Wrap your <App /> inside <BrowserRouter />
Now validate response if username/password are correct using service call.
Then this.route.navigate(['/']);
This will navigate user to home page of app after successful login.
Heres What I did, keep in mind I set up my backend with express/node.
I used Axios to fetch from my api.
onSubmit = (e) => {
e.preventDefault();
axios.get('API_PATH')
.then(res => {
const user = res.data[0].username;
const password = res.data[0].password;
const username = this.state.username;
const passwordEntered = this.state.password;
if(username === '' && passwordEntered === ''){
document.getElementById('status').innerHTML = '<p>Please Enter A Valid Username and Password</p>';
}else if(user === username && passwordEntered === password){
document.getElementById('status').innerHTML = '';
console.log(user, password)
}else{
document.getElementById('status').innerHTML = '<p>Please Enter A Valid Username and Password</p>';
}
})
.catch(error => {
console.log(error);
});
}
Here is the form I used.
<Form
>
<Form.Row>
<Form.Group as={Col}>
<Form.Label>Username</Form.Label>
<Form.Control
type="text"
name="username"
id="username"
value={this.state.value}
onChange={this.handleChange}
>
</Form.Control>
</Form.Group>
<Form.Group as={Col}>
<Form.Label>Password</Form.Label>
<Form.Control
type="text"
id="password"
name="password"
value={this.state.value}
onChange={this.handleChange}
/>
</Form.Group>
</Form.Row>
<Button className="btn btn-sm btn-light" onClick={this.onSubmit}>
<i style={redColor} className="fas fa-sign-in-alt"></i> Login
</Button>
</Form>

Angular 6 error doesn't fire

I am learning angular and for my example using Firebase createUserWithEmailAndPassword for sign-up. This returns a promise which i have changed to observable using from.
In firebase minimum password length is 6 characters. When i provide 5 characters, in the console i see the error message but in my sign-up event, success message shows rather than error. What am i missing here?
AuthService
import * as firebase from 'firebase';
import { throwError, from } from 'rxjs';
export class AuthService{
//user sign up, its a promise so listen for errors and log
signUpUser(email: string, password: string){
//return an observable using from
return from(
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(
(authData) => {
//good
console.log("User created successfully with payload-", authData);
return authData;
}
)
.catch(
(error) => {
//error
console.log(error);
return throwError(error);;
}
)
);
}
}
Sign-up component
onSignup(form: NgForm){
const email = form.value.email;
const password = form.value.password;
this.authService.signUpUser(email, password).subscribe(
(authData) => {
alert("Signup successful");
this.router.navigate(['/sign-in']);
},
(error) => {
alert(error.message);
}
);
}
Also i am using then in the authService method. How can i do .pipe(map(return authData.json()))?
Update 1:
Following helped and i am getting my error, on successful registration i am getting redirected to the sign-in view.
Convert promise to observable
AuthService
import { from } from 'rxjs';
signUpUserNew(email: string, password: string){
var subscription = from(firebase.auth().createUserWithEmailAndPassword(email, password));
return subscription;
}
Sign-up Component
//property to hold result of sign-up error
error = '';
onSignup(form: NgForm){
const email = form.value.email;
const password = form.value.password;
//this.authService.signUpUser(email, password);
this.authService.signUpUserNew(email, password)
.subscribe(
(firebaseUser) => {
console.log(firebaseUser);
this.router.navigate(['/sign-in']);
},
(error) => {
this.error = error.message;
}
);
}
View
<h2>Register</h2>
<div class="row">
<div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
<form (ngSubmit)="onSignup(f)" #f="ngForm">
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" name="email" ngModel class="form-control" #email="ngModel" required email>
<span class="help-block" *ngIf="!email.valid && email.touched">Please enter a valid email!</span>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" ngModel class="form-control" #password="ngModel" required minlength="6">
<span class="help-block" *ngIf="!password.valid && password.touched && !password.errors?.minlength">Please enter a valid password!</span>
<span class="help-block" *ngIf="!password.valid && password.touched && password.errors?.minlength">Password must be at least 6 characters long</span>
</div>
<p class="error" *ngIf="error">{{ error }}</p>
<button class="btn btn-primary" type="submit" [disabled]="!f.valid">Sign Up</button>
</form>
</div>
</div>
Result
Pending
Now i still need help implementing pipe and map operators.
I am getting the following error on .json:
[ts] Property 'json' does not exists on type 'UserCredential'
onSignup(form: NgForm){
const email = form.value.email;
const password = form.value.password;
//this.authService.signUpUser(email, password);
this.authService.signUpUserNew(email, password)
.pipe(
map(
(firebaseUser) => {
return firebaseUser.json();
}
)
)
.subscribe(
(firebaseUser) => {
console.log(firebaseUser);
this.router.navigate(['/sign-in']);
},
(error) => {
this.error = error.message;
}
);
}
Firstly, I guess you should call fromPromise instead of from, so try the following:
import 'rxjs/add/observable/fromPromise';
import { Observable } from "rxjs/Observable";
signUpUser(email: string, password: string){
//return an observable using fromPromise
const obs$ = fromPromise(
firebase.auth().createUserWithEmailAndPassword(email, password)
);
// you can call .pipe() here, and it will return an observable
return obs$.pipe(
map(x => console.log('PUT YOUR MAP FUNCTION HERE.')),
filter(x => console.log('Call filter() if you want'))
);
}
And you can subscribe to this observable
const subscription = this.authService.signUpUser(email, password).subscribe(
(firebaseUser) => {
console.log('firebase user: ', firebaseUser);
alert("Signup successful");
this.router.navigate(['/sign-in']);
},
(error) => {
alert(error.message);
}
);