AngularJS how to put data and id when user send form - javascript

I would like to send my api date and newsId together with data from form.
This is my form:
<div class="well">
<h4>Leave a Comment:</h4>
<form role="form" ng-submit="createComm(newComment)" novalidate>
<div class="form-group">
<input type="text" class="form-control" placeholder="Autor" ng-model="newComment.author">
</div>
<div class="form-group">
<textarea class="form-control" ng-model="newComment.comment" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
Controller:
.controller('CommentController',
function($scope, $routeParams, NewsModel){
var newsId = $routeParams.id;
path = 'getCommetnsByNewsId/'+newsId;
var comm = this;
var data = new Date().toLocaleString();
//comm.newComm.data = data; //this way?
$scope.createComm = function(comment){
NewsModel.create(comment).then(function (result){
initCreateComm();
})
}
function initCreateComm(){
comm.newComm = { comment: '', author: '', data: '', id: ''};
}
})
and service
service.createComm = function(comm){
return $http.post(getUrl(),comm);
}
How can I add to this code to send data and newsId? I do not want to keep data and id as html input.

You could send it after form submitting on create comment request with angular.extend:
$scope.createComm = function(comment){
NewsModel.create(angular.extend({}, {data: data, newsId: newsId}, comment)).then(function (result){
initCreateComm();
})
}

Related

Unable to redirect to homepage after posting a form - Express,EJS and JS

I have a view which contains a form and looks like this,
<form class="flex-form" id="form" method="">
<div class="form-component">
<label>Type</label>
<input type="text" id="type" name="type">
</div>
<div class="form-component">
<div class="form-component"><label><b>Contents</b></label></div>
<label>Savoury</label><input type="text" name="savoury" id="savoury">
<label>Fillings</label><input type="text" name="fillings" id="fillings">
<label>Amount</label><input type="text" name="amount" id="amount">
<div class="flex-component">
<button class="set-button" type="button" id="set">Set Item</button>
</div>
</div>
<div class="form-component">
<label class="description-label">Description</label>
<textarea class="fixed-textarea" id="description" name="description" cols="15" rows="10"></textarea>
</div>
<div class="form-component">
<label >Unit Price</label>
<input type="text" id="price" name="unit_price">
</div>
<div class="flex-component">
<button class="form-button" type="submit">Add</button>
</div>
</form>
I have a JavaScript that allows me to capture some intermediary information (via the Set Item button) from the form before the form gets submitted (via the Add Button). I want to handle the form's submission from the script since I need to capture the intermediary data.
let collectedItems = [];
let setter = document.getElementById('set');
let form = document.getElementById('form');
setter.addEventListener('click',getSetContent);
function getSetContent() {
let type = document.getElementById('savoury');
let fillings = document.getElementById('fillings');
let amount = document.getElementById('amount');
const content = {
type: type.value,
fillings: fillings.value.split(','),
amount: Number(amount.value)
};
collectedItems.push(content);
clearInputFields([type,fillings,amount]);
}
function clearInputFields(inputFields) {
inputFields.forEach(field => {
field.value = ''
});
console.log(collectedItems);
}
form.addEventListener('submit',submitForm);
function submitForm() {
const type = document.getElementById('type').value;
const desc = document.getElementById('description').value;
const price = Number(document.getElementById('price').value);
const content = collectedItems;
const data = {
type: type,
contents: content,
description: desc,
unit_price: price
};
post('http://localhost:8001/add/box',
{ 'Content-Type': 'application/json' },
JSON.stringify(data)
);
}
function post(endpoint,header,body) {
const response = fetch(endpoint,{ method: 'POST',headers: header,body: body });
response.then(
resp => {
if (resp.ok) {
console.log('form submitted');
} else {
console.log('form not submitted');
}
}
)
}
I then make a POST request using fetch() to an endpoint I have setup in Express which looks like this,
app.post('/add/box',(req,res) => {
const box: any = req.body;
console.log(box);
// DO SOME DB STUFF
res.redirect('/');
});
The form submission works as intended (logs to terminal using nodemon), however I am unable to redirect to the homepage. Instead I stay on the form page after the submission has occurred and I can't figure out why. Any help with this issue is much appreciated.

Cannot POST / login.html

I'm having trouble sending data to the server using a form. I already made a register form that works just fine, and for the most part my client side javascript for the login form is very similar to the javascript for the register form, and I just can't figure out why it won't work. It just gives me "Cannot POST /login.html"
Here's the login form html:
<div class="loginTitle">
<h1>Login</h1>
</div>
<div class="loginFormLayout">
<form method=post id="loginForm">
<div class="loginFormText">
<label for="username">Username</label>
</div>
<div class="loginFormEntry">
<input type="text" placeholder="Enter Username" name="loginUsername" required>
</div>
<div class="loginFormText">
<label for="password">Password</label>
</div>
<div class="loginFormEntry">
<input type="password" placeholder="Enter Password" name=loginPassword required>
</div>
<button type="submit" class="loginButton">Log In</button>
</form>
</div>
And here's the client side javascript:
//Login as an existing user
const login = document.getElementsByClassName('loginButton');
const loginForm = document.getElementById('loginForm');
const loginURL = 'http://localhost:3000/loginUser';
loginForm.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(loginForm);
let username = formData.get('loginUsername');
let password = formData.get('loginPassword');
loginForm.reset();
let user = { //Create a user object that will be sent to the backend and compared to the user database
username,
password
};
fetch(loginURL, { //Send the user object to the backend in JSON format to be checked against the database
method: 'POST',
body: JSON.stringify(user),
headers: {
'content-type': 'application/json'
}
})});
And the server side javascript for now, console logs are just to see if the info is getting up to the server
app.post('/loginUser', (req, res) => {
console.log(req.body.username);
console.log(req.body.password);
});
EDIT: I've also decided to post the info for my register form, which DOES work and uses similar logic to the login form. Maybe I'm missing something that isn't in the login logic
Register form html:
<div class="loginMenu">
<div class="loginTitle">
<h1>Register</h1>
</div>
<div id="registerWarning"></div>
<div class="loginFormLayout">
<form method="post" id="registerForm">
<div class="loginFormText">
<label for="username" id="newUsername">Username</label>
</div>
<div class="loginFormEntry">
<input type="text" placeholder="Create Username" name="username" required>
</div>
<div class="loginFormText">
<label for="password" id="newPassword">Password</label>
</div>
<div class="loginFormEntry">
<input type="password" placeholder="Create Password" name=password required>
</div>
<div class="loginFormText">
<label for="confirmPassword">Confirm Password</label>
</div>
<div class="loginFormEntry">
<input type="password" placeholder="Confirm Password" name="confirmPassword" required>
</div>
<button type="submit" class="registerButton">Register</button>
</form>
</div>
</div>
Register form client side javascript:
//Register a new user
const register = document.getElementsByClassName('registerButton');
const registerForm = document.getElementById('registerForm');
const registerURL = 'http://localhost:3000/createNewUser';
//When the user presses the register button, get the info from the form
registerForm.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(registerForm);
let newUsername = formData.get('username');
let newPassword = formData.get('password');
let confirmPassword = formData.get('confirmPassword')
registerForm.reset();
//Make sure new password and confirm password are equal
if (newPassword == confirmPassword) {
if (newUsername != "" && newPassword != ""){ //Make sure user enters something for both fields
let newUser = { //Create an object to send to the back end
newUsername,
newPassword
};
fetch(registerURL, { //Send the newUser object to the backend in JSON format to be added to the database
method: 'POST',
body: JSON.stringify(newUser),
headers: {
'content-type': 'application/json'
}
});
}
}
else { //If newPassword and confirmPassword are not equal, ask the user to enter them correctly
const registerWarning = document.getElementById('registerWarning');
registerWarning.innerText = 'Password and Confirm Password do not match';
registerWarning.style.padding = "10px";
registerWarning.style.background = 'red';
};
});
Register form server-side javascript:
app.post('/createNewUser', (req, res) => {
let newUsername = req.body.newUsername;
let newPassword = req.body.newPassword;
let newUserData = 'INSERT INTO users (username, password) VALUES (?, ?)';//Use the question marks as placeholders
//Use bcrypt to hash the password before putting it in the database
bcrypt.hash(newPassword, saltRounds, function(err, hash) {
db.query(newUserData, [newUsername, hash], function(err, result) {
if (err) throw err;
console.log('New user registered');
});
});
});
I figured it out, thanks to #Rocky Sims for the help.
Basically, the register form doesn't exist on the login html page, which was throwing an error up about how that doesn't exist before it could even get to the login code. So I just had to make seperate register.js and login.js files, as the issue was due to them being in the same file.
Try wrapping your form method (post) in quotes ('') like so <form method='post' id="loginForm">
Also the value for the name attribute for your password input should by in quotes. Like so <input type="password" placeholder="Enter Password" name='password' required>
I think the problem is that you haven't told the server what to send back to the client when the POST /loginUser endpoint gets called. Try adding res.sendStatus(200); at the end of your POST /loginUser handler function (so right after console.log(req.body.password);).

After Filling all Fields laravel sending 'required' error

I am trying to submit a form using axios post request in laravel. In this form i have 3 fields, name,age and a file called image.
here is the form
<form action="{{route('forms.store')}}" method="post" enctype="multipart/form-data">
#{{name}}
#csrf
<span v-if="errors.name">#{{errors.name[0]}}</span>
<label for="name">Name:</label>
<input type="text" name="name" id="name" v-model="name">
<span v-if="errors.age">#{{errors.age[0]}}</span>
<label for="age">Age:</label>
<input type="text" name="age" id="age" v-model="age">
<label for="image">Image:</label>
<span v-if="errors.image">#{{errors.image[0]}}</span>
<input type="file" name="image" id="image" #change="imageChanged">
<button #click.prevent="submitForm">Submit</button>
</form>
Here is my vueJs code:
const app = new Vue({
el: '#app',
data:{
name:'',
age:'',
image:'',
errors:{}
},
methods:{
imageChanged(e){
app.image = e.target.files[0]
console.log(e.target.files[0]);
},
submitForm(){
const config = { headers: { 'Content-Type': 'multipart/form-data' } };
const fd = new FormData(this.$data);
fd.append('image',this.image);
axios.post('{{route('forms.store')}}',this.fd,config).then((response)=>{
console.log(response.data);
}).catch((error)=>{
//console.log(error.response.data);
this.errors = error.response.data.errors;
})
}
}
});
And here is my controller
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'age' => 'required',
]);
if ($request->hasFile('image')) {
$image = $request->file('image');
return $ext = $image->extension();
} else {
return "NOT OK";
}
}
So here I am validating name and age. But my problem is when I fill the form and submit the form,
It sends back errors that name and age field is required.
where am I doing wrong and how to receive this data in the controller.
Thank you in advance.
I believe your code is in error in this part. changes:
axios.post('{{route('forms.store')}}',this.fd,config)
to:
axios.post('{{route('forms.store')}}',fd,config)

how to post data to server using angularJS, web api

i am new to angularJS and trying to figure out, how to post data to my server, problem is that my post to server is successful and it create new record but all is empty(null).
Thanks for any advice
JS:
$scope.addChannel = function () {
var channels = [];
//var newChannel = {
// Name: $scope.Name
//};
//clearing error message
$scope.errorMessage = "";
$http.post("api/Channel/channels", newChannel)
.success(function (newChannel) {
//on success
$scope.channels.push({ "Name": $scope.Name });
console.log("data added");
// newChannel.push(response.data);
newChannel = {};
}, function () {
//on failure
$scope.errorMessage = "Failed to save data";
})
}
HTML:
<div ng-controller="ChannelController">
<div class="col-md-4 col-lg-4 col-sm-4">
<form novalidate name="newUser"ng-submit="addChannel()">
<div class="form-group">
<label for="name">Channel</label>
<input class="form-control" type="text" id="Name" name="Name" ng-model="newChannel.Name" />
</div>
<div class="form-group">
<input type="submit" value="Add" class="btn btn-success" />
</div>
</form>
<a ng-href="/Dashboard#/channels">Return to dashboard</a>
</div>
<div class="has-error" ng-show="errorMessage">
{{errorMessage}}
</div>
Channel Controller
[HttpPost("channels")]
public async System.Threading.Tasks.Task Create(Channel channel)
{
await _channelRepository.CreateChannel(channel);
}
Repository
public async System.Threading.Tasks.Task CreateChannel(Channel channel)
{
_context.Channel.Add(channel);
await _context.SaveChangesAsync();
}
Check if you name properties correctly in object that you send to server, property names are case sensitive. Looks like you have in js
var customer = {name: 'foo', lastName: 'bar'};
and on server you try to deserialize your JSON to this entity
class Customer {
public Name {get;set;} //note prop names are capitalized
public LastName {get;set;}
}

Symfony2: manually submit a form without class via AJAX

We have an old website where I have implemented a form that is sent by AngularJS to a PHP script and after processing an email message get sent. If the form is not valid the PHP script returns a JSON with the validation errors. Since we already use Symfony for some other applications (REST APIs), I thought it would be nice to reimplement my plain PHP script in Symfony.
For the sake of simplicity I put only a small but relevant fragment of my code. This is what I have:
HTML (ng-app is bound on body tag, not shown here):
<form name="infoscreenForm" class="form-horizontal" enctype="multipart/form-data" ng-controller="FormController">
<div class="form-group">
<div class="col-lg-1 control-label">*</div>
<div class="col-lg-11 input-group">
<input type="text" class="form-control" id="contact_person"
name="contact_person" ng-model="formData.contactPerson"
placeholder="Kontaktperson">
</div>
<span class="text-warning" ng-show="errors.contactPerson">
{{ errors.contactPerson }}
</span>
</div>
<div class="form-group">
<div class="col-lg-1 control-label">*</div>
<div class="col-lg-11 input-group">
<span class="input-group-addon">#</span>
<input type="email" class="form-control" id="email" name="email"
ng-model="formData.email" placeholder="E-Mail">
</div>
<span class="text-warning" ng-show="errors.email">
{{ errors.email }}
</span>
</div>
<div class="form-group">
<div class="col-lg-1 control-label"> </div>
<div class="col-lg-11 input-group">
<input type="file" class="form-control" id="file" name="file"
file-model="formData.file"
accept="application/pdf,image/jpeg,image/png">
</div>
<span class="text-warning" ng-show="errors.file">
{{ errors.file }}
</span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default" id="submit"
name="submit" ng-click="submitForm()">
Formular absenden
</button>
</div>
</form>
JS:
var app = angular.module('InfoscreenApp', []);
app.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function () {
scope.$apply(function () {
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
app.factory('multipartForm', ['$http', function ($http) {
return {
post : function (uploadUrl, data) {
var fd = new FormData();
for (var key in data) {
fd.append(key, data[key]);
}
return $http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers : { 'Content-Type': undefined }
});
}
};
}]);
app.controller('FormController', ['$scope', 'multipartForm', function ($scope, multipartForm) {
$scope.formData = {};
$scope.submitForm = function () {
var uploadUrl = 'http://localhost:8000/infoscreen';
multipartForm.post(uploadUrl, $scope.formData)
.then(function (data) {
console.log(data);
if (data.success) {
$scope.message = data.data.message;
console.log(data.data.message);
} else {
$scope.errors = data.data.errors;
}
});
};
}]);
With the plain PHP script everything works fine. Here is what I tried to do in Symfony:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
class DefaultController extends Controller
{
/**
* #Route("/infoscreen", name="infoscreen")
*/
public function infoscreenAction(Request $request)
{
$defaultData = array('message' => 'infoscreenForm');
$form = $this->createFormBuilder($defaultData)
->add('contactPerson', TextType::class, array(
'constraints' => array(
new NotBlank(),
)
))
->add('email', EmailType::class, array(
'constraints' => array(
new NotBlank(),
new Email(),
)
))
->add('file', FileType::class)
->add('submit', SubmitType::class)
->getForm();
;
$form->submit($request->request->get($form->getName()));
$data = $form->getData();
if ($form->isValid()) {
echo 'Alles ok';
// send an email
}
$errors = array();
$validation = $this->get('validator')->validate($form);
foreach ($validation as $error) {
$errors[$error->getPropertyPath()] = $error->getMessage();
}
$response = new Response();
$response->setContent(json_encode(array(
'form_data' => $data,
'errors' => $errors,
)));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
}
CSRF is disabled in config.yml. The form is not bound to an entity class. After submitting the form I get the following object in the console:
{
data: Object,
status: 200,
config: Object,
statusText: "OK"
}
The important part is in data: Object:
{
form_data: {
contactPerson: null,
email: null,
message: "infoscreenForm",
file: null
},
errors : {
children[contactPerson].data = "This value should not be blank",
children[email].data = "This value should not be blank"
}
}
This happens when I submit the form with some values entered in the fields. It seems that the submitted data is not bound to the form in the controller. I'm probably missing something, but I stuck here and have no idea how to proceed. I tried with $form->bind($request), $form->handleRequest($request) and few other things, but it didn't work. Even if I bind the fields individually, I still don't get their values in the form.
Can somebody please help me.
Thanks in advance.
Try
$this->get('form.factory')->createNamedBuilder(null, 'form', $defaultData)
instead of
$this->createFormBuilder($defaultData)

Categories

Resources