why i get a "?" in my angular2 url when i use a http post rest api - symfony

hello i'm new in Angular , i'm trying to send to my backend(Symfony2.8) a Subject , Email and Message . when i route the the localhost:4200/contact , i get no error , no excption and the nothing happend , the URL becomes localhost:4200/contact? . here is my component,service and html file: (BTW i used this method to add and object to the database and it works normally)
export class ContactComponent {
contactForm: any;
constructor(private formBuilder: FormBuilder, public router: Router ,private cService: ContactService) {
this.contactForm = this.formBuilder.group({
'subject': ['', Validators.required],
'email' : ['', Validators.required],
'msg': ['', Validators.required],
});
}
sendMessage()
{
// console.log(this.contactForm.value.subject,this.contactForm.value.email,this.contactForm.value.msg);
this.cService.sendMsg(this.contactForm.value.subject,this.contactForm.value.email,
this.contactForm.value.msg)
.subscribe(
response => {
alert("Thanks for contacting us");
},
error => {
alert(error);
}
);
export class ContactService {
url:string = '/web/contactus';
constructor (private http: Http) {
}
sendMsg(subject: string,email: string, msg: string): Observable<any> {
let body = JSON.stringify({
subject,
email,
msg
} || null);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
console.log(body);
return this.http.post(this.url, body, options)
.map(res => res.json().data)
.do(data => console.log(JSON.parse(JSON.stringify(data || null ))))
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body || { };
}
<form [formGroup]="contactForm" (submit)="sendMessage()">
<div class="form-group">
<label >Subject</label>
<input class="form-control" formControlName="subject" placeholder="Subject"/>
<span *ngIf="!contactForm.controls.subject.valid">required</span>
</div><!-- /.form-group -->
<div class="form-group">
<label>E-mail</label>
<input class="form-control" formControlName="email" placeholder="Email"/>
<span *ngIf="!contactForm.controls.email.valid">required</span>
</div><!-- /.form-group -->
<div class="form-group">
<label >Message</label>
<textarea class="form-control" formControlName="msg" rows="6"></textarea>
<span *ngIf="!contactForm.controls.msg.valid">required</span>
</div><!-- /.form-group -->
<button class="btn btn-primary pull-right" type="submit" [disabled]="!contactForm.valid">Post Message</button>
</form>

Looks like it is throwing some exception. In console click on the preserve log and then try the same. You may see some exceptions

Related

Next.js secure authenticaton

I am trying to make a secure authentication with next.js
I've followed this article because it shows how do to it with api route and proxy server, but I do not understand why he uses this http-proxy module
I did the same thing without it and it seems to work perfectly fine.
Here is my pages/login.js file
import { Button } from '#mui/material'
import { useState } from 'react'
export default function loginPage() {
const [message, setMessage] = useState();
const handleSubmit = async (event) => {
event.preventDefault();
const data = {
username: event.target.username.value,
password: event.target.password.value
};
const response = await fetch('/api/login', {
headers: {
'Content-Type': 'application/json'
},
method: 'POST',
body: JSON.stringify(data),
});
setMessage(response.message);
}
return (
<div className="block">
<form onSubmit={handleSubmit}>
{message ? <p className="message">{message}</p> : ""}
<label htmlFor="first">Username</label>
<input type="text" id="username" name="username" variant="outlined" required />
<label htmlFor="last">Password</label>
<input type="text" id="password" name="password" variant="outlined" required />
<div>
<Button className="btn" type="submit" variant="outlined">Submit</Button>
</div>
</form>
</div>
)
}
Here is my pages/api/[...catchAll].js
import Cookies from "cookies"
export default async function handler(req, res) {
console.log("HERE");
const response = await fetch("http://localhost:7000/register", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(req.body)
}).then((res) => res.json());
const cookies = new Cookies(req, res);
cookies.set("authorization", response.token, {
httpOnly: true,
sameSite: "lax",
maxAge: 100000
});
res.status(200).json(response)
}
My front-end pages/login.js sends a request to pages/api[...catchAll].js and then a request to my back-end is being made. My back-end returns
{
message: "success",
token: crypto.randomBytes(48).toString('hex')
}
and then pages/api/[...catchAll].js sets my cookies. Why in the article the person uses the httpProxy module ? Is it more secure ? Why ?
I've seen this technique in a lot of places because of secure measurements, but I do not understand why they use this proxy server.
Could someone please explain ?

How do I manipulate data received from an API endpoint and submit to database

The aim of my application is to take a URL submitted by a user in a form, pull data from it, manipulate that data, and then submit the manipulated data to a Postgres database.
Current Status
So far I have developed a form on the front end of the application (irrelevant validation / styling code has been removed from this excerpt):
const Feeds = ({ visible }) => {
const handleSubmit = async (e) => {
e.preventDefault();
try {
const body = { feedTitle, websiteUrl, currency, feedUrl };
await fetch('/api/form', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
console.log('body: ', body);
} catch (error) {
console.error(error);
}
};
return (
<Form onSubmit={(e) => handleSubmit(e)} id="myForm" visible={visible}>
<HeaderContainer>
<Header>Add a new feed</Header>
<HeaderDescription>Please complete all of the required fields below and submit to add a new feed.</HeaderDescription>
</HeaderContainer>
<FormContainer>
<InputContainer>
<Label>Feed title</Label>
<Input type="text" placeholder="" value={feedTitle} onChange={(e) => handleChangeFeedTitle(e)} />
</InputContainer>
<InputContainer>
<Label>Website url</Label>
<Input type="text" placeholder="" value={websiteUrl} onChange={(e) => handleChangeWebsiteUrl(e)} />
</InputContainer>
<InputContainer>
<Label>Currency</Label>
<Select onChange={(e) => handleChangeCurrency(e)} name="currency" id="currency-select">
{currencies.map((option, index) => (
<option key={index} value={option.value}>
{option.text}
</option>
))}
</Select>
</InputContainer>
<InputContainer>
<Label>Feed url</Label>
<Input type="text" placeholder="" value={feedUrl} onChange={(e) => handleChangeFeedUrl(e)} />
</InputContainer>
</FormContainer>
{allValid ? <Button type="submit" form="myForm">Save</Button> : <DisabledButton>Save</DisabledButton>}
</Form>
)
};
export default Feeds;
On submission, this POST request hits the /api/form API endpoint:
const handler = async (req, res) => {
const body = req.body;
const response = await fetch(body.feedUrl)
.then(res => res.text())
.then(content => console.log(content))
.catch(err => console.error(err));
console.log('body: ', body);
res.status(200).json({ data: `${body}` })
};
export default handler;
Here I have simply console logged the content coming back from the API. Instead I need to manipulate it using a function and then submit the manipulated data to a database using a separate function.
The Problem
My question is, where should I implement these functions so that they trigger on the server side?
Thanks

Can't update email from Firebase (auth)

I got a Firebase auth you can login and logout.
But I want that the currentUser can change the email.
I have a password reset function that send a email with a link and you can reset your password but It didn't work with the email change.
This is the profile page
Here is the code
<template>
<div class="container">
<div class="card">
<div class="card-header">
<h1>Profile</h1>
</div>
<div v-if="!isHidden" class="alert alert-success" role="alert">
<strong>Email sended</strong>
</div>
<div class="card-body">
<form action="#" #submit.prevent="submit" #click="isHidden = !isHidden">
<div class="form-group row mb-0">
<div class="col-md-7 offset-sm-6 offset-md-7 offset-xl-9">
<input type="submit" class="btn btn-primary" #click="resetPassword" value="Reset your password">
</div>
</div>
</form>
<div class="">
<input type="email" class="form-control" v-model="email">
<input type="submit" class="btn btn-primary" #click="resetEmail" value="Reset your email">
</div>
</div>
</div>
</div>
</template>
<script>
import firebase from "firebase";
/* eslint-disable */
export default {
data() {
return {
email: "",
password: "",
isHidden: true
};
},
methods: {
login(e) {
firebase.auth().signInWithEmailAndPassword(this.email, this.password)
.then(user => {
alert('You are logged in as ' + this.email);
this.$router.push('/index');
location.reload();
},
err => {
alert(err.message);
})
e.preventDefault();
},
resetPassword() {
const auth = firebase.auth();
auth.sendPasswordResetEmail(auth.currentUser.email).then(() => {
console.log('Email send');
// Email sent.
}).catch((error) => {
// An error happened.
console.log(error);
});
},
resetEmail() {
const auth = firebase.auth();
auth.updateEmail(this.email).then(() => {
console.log('Email changed');
// Email sent.
}).catch((error) => {
// An error happened.
console.log(error);
});
}
}
};
</script>
When I run this I get this error:
Uncaught TypeError: auth.updateEmail is not a function
at VueComponent.resetEmail (Profile.vue?5a88:64)
at invoker (vue.runtime.esm.js?2b0e:2023)
at HTMLInputElement.fn._withTask.fn._withTask (vue.runtime.esm.js?2b0e:1822)
What do I do wrong because I read the Firebase doc and checkt on Google but I do something wrong.
The updateEmail() method is not a method of the "root" Firebase Auth service but a method of a User.
So you have to do something along the following lines:
const auth = firebase.auth();
auth.currentUser.updateEmail(this.email).then(() => {...});

How to upload image in angular2? in post method

html
<div class="form-group ">
<input type="file" [(ngModel)]="model.files" name="files" #files="ngModel" class="form-control" id="files" multiple="">
</div>
<div class="form-group ">
<label for="productname">Name</label>
<input type="text" class="form-control" id="productname" required minlength="5" pattern="^[a-zA-Z0-9/,-. ]*$" maxlength="30" [(ngModel)]="model.productname" name="productname" #productname="ngModel">
</div>
<div class="form-group ">
<label for="sales">Sales price/rate</label>
<input type="text" class="form-control" id="sales" pattern="[0-9]+" required minlength="0" maxlength="10" [(ngModel)]="model.sales" name="sales" #sales="ngModel">
</div>
<button type="submit" class="btn btn-success " (click)="save(productname,sales,files);onChangeroot(root)">Submit</button>
component.ts
export class NewProductComponent {
productservice:ProductsService
selectedFile = null;
onfileSelected(event){
console.log(event);
this.selectedFile =<File>event.target.files[0];
}
save1(productname,sales,files)
{
let obj = {
'pro_name':productname.value,
'sales':sales.value,
'image':files.value
}
var json = JSON.stringify(obj)
console.log(json)
const fd = new FormData();
fd.append('image', this.selectedFile , this.selectedFile.name );
this.http.post('http://127.0.0.1:8000/product/images/',fd)
this.service.save_user1(json).subscribe(response => console.log('Inserted Successfully'),
error => console.log(error));
}
}
service.ts
export class ProductsService {
save_user1(exp_data:any): Observable<any[]>{
console.log("console",exp_data)
let headers = new Headers({ 'Content-Type': 'application/json'});
let options = new RequestOptions({ headers: headers });
console.log("options",options)
return this.http.post("http://127.0.0.1:8000/product/", exp_data, options)
.map(response => response.json())
.catch(error => Observable.throw(error.statusText));
};
}
After selecting image in console event is working while submitting the form except that image all other data are so successfully stored in database.
I am tried in this way but not able to post image,.so please help me how to do that ?
I think your service method need to be change. Usually we have to send file as multipart form data. My working copy is :
let formData: FormData = new FormData();
formData.append('file', this.imageFile);
this.http.post(this.url , formData) .subscribe(
(result) => {
console.log(result);
},
(error) => {
console.error(error);
}
);

Meteor 1.3 + React Stripe Subscription

I'm following along TheMeteorChef's Building a SaaS with Meteor: Stripe which is built with blaze templates. Tried to use react instead but I think I failed somewhere along the way. I've gotten to about half of the part 1 of 2 but enough to test if signing up with plan should work or not. Well, it doesn't work but also doesn't give any errors in console... I have very little experience, just started actually, so I'm hoping I could get some help. Thank you.
~/client/helpers/stripe.js
Meteor.startup(function() {
const stripeKey = Meteor.settings.public.stripe.testPublishableKey;
Stripe.setPublishableKey(stripeKey);
STRIPE = {
getToken: function(domElement, card, callback) {
Stripe.card.createToken(card, function(status, response) {
if(response.error) {
Bert.alert(response.error.message, "danger");
} else {
STRIPE.setToken(response.id, domElement, callback);
}
});
},
setToken: function(token, domElement, callback) {
$(domElement).append($('<input type="hidden" name="stripeToken" />').val(token));
callback();
}
}
});
~/client/components/SignUp.jsx
import React, {Component} from 'react';
import PlanSelectForm from '../components/PlanSelectForm.jsx';
import CreditCardForm from '../components/CreditCardForm.jsx';
export default class SignUp extends Component {
componentDidMount() {
$.validator.addMethod('usernameRegex', function(value, element) {
return this.optional(element) || /^[a-zA-Z0-9-_]+$/i.test(value);
}, "Username must contain only letters, numbers, underscores and dashes.");
$('#application-signup').validate({
rules: {
username: {
required: true,
usernameRegex: true,
minlength: 6
},
emailAddress: {
required: true,
email: true
},
password: {
required: true,
minlength: 6
}
},
messages: {
username: {
required: 'You can\'t leave this empty',
usernameRegex: 'You can use letter, numbers, underscores, and dashes.',
minlength: 'Too short. Use at least 6 characters.'
},
emailAddress: {
required: 'You can\'t leave this empty',
email: 'Email is invalid or already taken.'
},
password: {
required: 'You can\'t leave this empty',
minlength: 'Too short. Use at least 6 characters.'
}
},
handleSubmit: function() {
STRIPE.getToken('#application-signup', {
number: $('[data-stripe="cardNumber"]').val(),
exp_month: $('[data-stripe="expMo"]').val(),
exp_year: $('[data-stripe="expYr"]').val(),
cvc: $('[data-stripe="cvc"]').val()
}, function() {
const customer = {
username: $('[name="username"]').val(),
emailAddress: $('[name="emailAddress"]').val(),
password: $('[name="password"]').val(),
plan: $('[name="selectPlan"]:checked').val(),
token: $('[name="stripeToken"]').val()
};
const submitButton = $('input[type="submit"]').button('loading');
Meteor.call('createTrialCustomer', customer, function(error, response) {
if(error) {
alert(error.reason);
submitButton.button('reset');
} else {
if(response.error) {
alert(response.message);
submitButton.button('reset');
} else {
Meteor.loginWithPassword(customer.emailAddress, customer.password, function(error) {
if(error) {
alert(error.reason);
submitButton.button('reset');
} else {
Router.go('/chart');
submitButton.button('reset');
}
});
}
}
});
});
}
});
}
render() {
console.log(this);
return (
<form id="application-signup" className="signup">
<h4>Account details</h4>
<div className="form-group">
<label for="username">Username</label>
<input type="text"
name="username"
className="form-control"
placeholder="Username" />
</div>
<div className="form-group">
<label for="emailAddress">Email Address</label>
<input type="email"
name="emailAddress"
className="form-control"
placeholder="Email Address" />
</div>
<div className="form-group">
<label for="password">Password</label>
<input type="password"
name="password"
className="form-control"
placeholder="Password" />
</div>
<h4 className="page-header">Payment Information</h4>
<label>Which plan sounds <em>amazing</em>?</label>
<PlanSelectForm />
<div className="form-group">
<CreditCardForm />{/* data={signup} /> */}
</div>
<div className="form-group">
<input type="submit"
className="btn btn-success btn-block"
data-loading-text="Setting up your trial..."
value="Put me on the rocketship" />
</div>
</form>
)
}
}
Note: In the tutorial, TheMeteorChef uses a dynamic template for CreditCardForm with data="signup" context. I think he mentions the CC template will be used again after but I haven't gone that far yet. Anyways, I didn't know what "signup" means... so I left it commented out. If you know, please let me know about that as well.
~/client/components/PlanSelectForm.jsx
import React, {Component} from 'react';
export default class PlanSelectForm extends Component {
componentDidMount() {
const firstPlanItem = $('.select-plan a:first-child');
firstPlanItem.addClass('active');
firstPlanItem.find('input').prop('checked', true);
}
plans() {
return Meteor.settings.public.plans;
}
handleClickItem(e) {
const parent = $(e.target).closest('.list-group-item');
console.log(parent);
parent.addClass('active');
$('.list-group-item').not(parent).removeClass('active');
$('.list-group-item').not(parent).find('input[type="radio"]').prop('checked', false);
parent.find('input[type="radio"]').prop('checked', true);
}
render() {
let plans = this.plans();
if(!plans) {
return(<div>loading...</div>);
}
return (
<div className="list-group select-plan">
{plans.map((plan) => {
return (
<a key={plan.id}
href="#"
className="list-group-item"
onClick={this.handleClickItem.bind(this)}>
<input key={plan.id}
type="radio"
ref="selectPlan"
id={`selectPlan_${plan.id}`}
value={plan.name} />
{plan.name} {plan.amount.usd}/{plan.interval}
</a>
)
})}
</div>
)
}
}
~/client/components/CreditCardForm.jsx
import React, {Component} from 'react';
export default class CreditCardForm extends Component {
render() {
return (
<div>
<div className="row">
<div className="col-xs-12">
<div className="form-group">
<label className="text-success">
<i className="fa fa-lock"></i> Card Number
</label>
<input type="text"
data-stripe="cardNumber"
className="form-control card-number"
placeholder="Card Number" />
</div>
</div>
</div>
<div className="row">
<div className="col-xs-4">
<label>Exp. Mo.</label>
<input type="text"
data-stripe="expMo"
className="form-control exp-month"
placeholder="Exp. Mo." />
</div>
<div className="col-xs-4">
<label>Exp. Yr.</label>
<input type="text"
data-stripe="expYr"
className="form-control exp-year"
placeholder="Exp. Yr." />
</div>
<div className="col-xs-4">
<label>CVC</label>
<input type="text"
data-stripe="cvc"
className="form-control cvc"
placeholder="CVC" />
</div>
</div>
</div>
)
}
}
~/server/signup.js
Meteor.methods({
createTrialCustomer: function(customer) {
check(customer, {
name: String,
emailAddress: String,
password: String,
plan: String,
token: String
});
const emailRegex = new RegExp(customer.emailAddress, 'i');
const usernameRegex = new RegExp(customer.username, 'i');
const lookupEmail = Meteor.users.findOne({'emails.address': emailRegex});
const lookupUser = Meteor.users.findOne({'username': usernameRegex});
if(!lookupEmail) {
if(!lookupUser) {
const newCustomer = new Future();
Meteor.call('stripeCreateCustomer', customer.token, customer.emailAddress, function(error, stripeCustomer) {
if(error) {
console.log(error);
} else {
const customerId = stripeCustomer.id,
plan = customer.plan;
Meteor.call('stripeCreateSubscription', customerId, plan, function(error, response) {
if(error) {
console.log(error);
} else {
try {
const user = Accounts.createUser({
username: customer.username,
email: customer.emailAddress,
password: customer.password
});
const subscription = {
customerId: customerId,
subscription: {
plan: {
name: customer.plan,
used: 0
},
payment: {
card: {
type: stripeCustomer.sources.data[0].brand,
lastFour: stripeCustomer.sources.data[0].last4
},
nextPaymentDue: response.current_period_end
}
}
}
Meteor.users.update(user, {
$set: subscription
}, function(error, response) {
if(error) {
console.log(error);
} else {
newCustomer.return(user);
}
});
} catch(exception) {
newCustomer.return(exception);
}
}
});
}
});
return newCustomer.wait();
} else {
throw new Meteor.Error('username-exists', 'Sorry, that username is already active!');
}
} else {
throw new Meteor.Erro('email-exists', 'Sorry, that email is already active!')
}
},
})
~/server/stripe.js
const secret = Meteor.settings.private.stripe.testSecretKey;
const Stripe = StripeAPI(secret);
Meteor.methods({
stripeCreateCustomer: function(token, email) {
check(token, String);
check(email, String);
const stripeCustomer = new Future();
Stripe.customers.create({
source: token,
email: email
}, function(error, customer) {
if(error){
stripeCustomer.return(error);
} else {
stripeCustomer.return(customer);
}
});
return stripeCustomer.wait();
},
stripeCreateSubscription: function(customer, plan) {
check(customer, String);
check(plan, String);
const stripeSubscription = new Future();
Stripe.customers.createSubscription(customer, {
plan: plan
}, function(error, subscription) {
if(error) {
stripeSubscription.return(error);
} else {
stripeSubscription.return(subscription);
}
});
return stripeSubscription.wait();
}
})
packages
"dependencies": {
"meteor-node-stubs": "~0.2.0",
"react": "^15.0.2",
"react-addons-css-transition-group": "^15.0.2",
"react-dom": "^15.0.2",
"react-mounter": "^1.2.0"
},
accounts-base
accounts-password
session
check
random
kadira:flow-router
ultimatejs:tracker-react
meteortoys:allthings
fourseven:scss
fortawesome:fontawesome
themeteorchef:bert
themeteorchef:jquery-validation
momentjs:moment
mrgalaxy:stripe
Thanks for reading, I hope that it wasn't painful.
did you import mrgalaxy:stripe ?
it will be something like
import { StripeAPI } from 'meteor/mrgalaxy:stripe'
I guess.
anw, you can install by npm :
npm install stripe
import Stripe from 'stripe'
then
Stripe('your_secret_key')

Resources