File uploading not working MEAN stack - javascript

I'm beginner in MEAN development and trying to implement CRUD application using it. Initially I've successfully completed my CRUD app using MEAN. Now I'm trying to upload file using angular.js. I got to know that Angular.js doesn't support file upload functionality so by using https://www.youtube.com/watch?v=vLHgpOG1cW4 and https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
I'm trying to implement this feature.
But somehow the code is not working and giving some angular.js error on firebug console.
Error: [$injector:unpr] http://errors.angularjs.org/1.5.0/$injector/unpr?p0=multipartFormProvider%20%3C-%20multipartForm%20%3C-%20AppCtrl....so on
Following is my code:
app/public/controller.js
var myApp = angular.module('myApp', []);
myApp.controller('AppCtrl', ['$scope', '$http', 'multipartForm', function ($scope, $http, multipartForm) {
console.log("Hello World from controller");
$scope.contact = {};
var refresh = function () {
$http.get('/contactlist').success(function (response) {
console.log("I got the data that I requested");
$scope.contactlist = response; // This will put data into our html file
$scope.contact = "";
});
};
refresh();
$scope.addContact = function () {
console.log($scope.contact);
var uploadUrl = '/upload';
multipartForm.post('/contactlist', uploadUrl, $scope.contact).success(function (response) {
console.log(response);
refresh();
});
};
$scope.remove = function (id) {
console.log(id);
$http.delete('/contactlist/' + id).success(function (response) {
refresh();
});
};
$scope.edit = function (id) {
console.log(id);
$http.get('/contactlist/' + id).success(function (response) {
$scope.contact = response;
});
};
$scope.update = function () {
console.log($scope.contact._id);
//$scope.contact means sending all form data to server
$http.put('/contactlist/' + $scope.contact._id, $scope.contact).success(function (response) {
refresh();
});
};
$scope.deselect = function () {
$scope.contact = "";
};
}]);
app/public/index.html
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css">
<title>Contact List App</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="container" ng-controller="AppCtrl">
<div class="panel panel-default">
<div class="panel-heading"><h4 class="panel-title">Details</h4></div>
<div class="panel-body">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" placeholder="Name" ng-model="contact.name">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email" ng-model="contact.email">
</div>
<div class="form-group">
<label for="Contact">Contact</label>
<input class="form-control" placeholder="Contact" ng-model="contact.number">
</div>
<div class="form-group">
<label for="country">Country</label>
<select class="form-control" ng-model="contact.country">
<option value="">Select</option>
<option value="India">India</option>
<option value="Australia">Australia</option>
<option value="Germany">Germany</option>
<option value="Spain">Spain</option>
<option value="Japan">Japan</option>
<option value="Switzerland">Switzerland</option>
<option value="USA">USA</option>
<option value="Sri Lanka">Sri Lanka</option>
<option value="South Africa">South Africa</option>
<option value="England">England</option>
<option value="New Zealand">New Zealand</option>
</select>
</div>
<div class="form-group">
<label for="gender">Gender</label>
<div class="radio">
<label>
<input type="radio" name="gender" id="optionsRadios1" value="Male" ng-model="contact.gender">
Male
</label>
<label>
<input type="radio" name="gender" id="optionsRadios2" value="Female" ng-model="contact.gender">
Female
</label>
</div>
</div>
<div class="form-group">
<label for="education">Education</label>
<div class="checkbox">
<label>
<input type="checkbox" name="education" ng-model="contact.education.MCA">
MCA
</label>
<label>
<input type="checkbox" name="education" ng-model="contact.education.BE">
BE
</label>
<label>
<input type="checkbox" name="education" ng-model="contact.education.ME">
ME
</label>
<label>
<input type="checkbox" name="education" ng-model="contact.education.BCA">
BCA
</label>
</div>
</div>
<div class="form-group">
<label>Avatar</label>
<input type="file" file-model="contact.file">
</div>
<div class="well well-lg text-center bg-gray">
<button class="btn btn-primary" ng-click="addContact()">Add Contact</button>
<button class="btn btn-info" ng-click="update()">Update</button>
<button class="btn btn-info" ng-click="deselect()">Clear</button>
</div>
</div>
<h4>Listing</h4>
<input type="text" class="form-control" ng-model="contact.names" placeholder="Instant result search">
<table class="table table-bordered">
<tr>
<th>Name</th>
<th>Email</th>
<th>Number</th>
<th>Country</th>
<th>Gender</th>
<th>Education</th>
</tr>
<tr ng-repeat="contact in contactlist| filter:contact.names|orderBy:-1">
<td>{{contact.name}}</td>
<td>{{contact.email}}</td>
<td>{{contact.number}}</td>
<td>{{contact.country}}</td>
<td>{{contact.gender}}</td>
<td>
{{contact.education}}
</td>
<td>
<button class="btn btn-danger" ng-click="remove(contact._id)">Remove</button>
<button class="btn btn-warning" ng-click="edit(contact._id)">Edit</button>
</td>
</tr>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<script src="controllers/controller.js"></script>
<script src="services/multipartForm.js"></script>
<script src="directives/fileModel.js"></script>
</body>
</html>
app/public/services/multipartForm.js
myApp.service('multipartForm', ['$http', function ($http) {
this.post = function (uploadUrl, data) {
var fd = new FormData();
for (var key in data)
fd.append(key, data[key]);
$http.post(uploadUrl, fd, {
transformRequest: angular.indentity,
headers: {'Content-Type': undefined}
});
};
}]);
And finally on Node/Express Side: app/server.js
var express = require('express');
var app = express(); // using this we can use commands, function of express in this (server.js) file
var mongojs = require('mongojs');
var db = mongojs('contactlist', ['contactlist']); // Means which mongodb database & collection we are going to use
var bodyParser = require('body-parser');
var multer = require('multer');
// To test whether server is running correctly
/* app.get("/", function(req, res){
res.send("Hello world from server.js");
}); */
app.use(express.static(__dirname + "/public")); // express.static means we are telling the server to look for static file i.e. html,css,js etc.
app.use(multer({dest: './uploads/'}).single('photo'));
app.use(bodyParser.json()); // To parse the body that we received from input
//This tells the server to listen for the get request for created contactlist throughout
app.get('/contactlist', function (req, res) {
console.log("I received a GET request");
//Creating an array of above data
var contactlist = [person1, person2, person3];
// its going to respond to the GET request by sending back contactlist data in JSON format which controller can use
res.json(contactlist);
db.contactlist.find(function (err, docs) {
console.log(docs);
res.json(docs);
});
});
// listens for the POST request from the controller
app.post('/contactlist', function (req, res) {
console.log(req.body);
db.contactlist.insert(req.body, function (err, doc) {
res.json(doc);
});
});
app.delete('/contactlist/:id', function (req, res) {
var id = req.params.id; // to get the value of id from url
console.log(id);
db.contactlist.remove({_id: mongojs.ObjectId(id)}, function (err, doc) {
res.json(doc);
});
});
app.get('/contactlist/:id', function (req, res) {
var id = req.params.id;
console.log(id);
db.contactlist.findOne({_id: mongojs.ObjectId(id)}, function (err, doc) {
res.json(doc);
});
});
app.put('/contactlist/:id', function (req, res) {
var id = req.params.id;
console.log(req.body.name);
db.contactlist.findAndModify({
query: {_id: mongojs.ObjectId(id)},
update: {$set: {
name: req.body.name,
email: req.body.email,
number: req.body.number,
country: req.body.country,
gender: req.body.gender,
education: req.body.education
}}, new : true}, function (err, doc) {
res.json(doc);
});
});
app.listen(3000);
console.log("Server running on port 3000");
Any help would be appreciated :)

Related

How do I make Javascript (node.js) wait while I submit the form?

I would like the program/script to stop/wait after "console.log ('3')" until you click "Finished!" (and prior download of data from the above form).
Clicking this button would be equivalent to restarting the program / script from "console.log ('4')".
How can this be achieved?
code in app.js:
var express = require('express');
var http = require('http');
var path = require("path");
var helmet = require('helmet');
var rateLimit = require("express-rate-limit");
const port = process.env.PORT || 3000;
const { MongoClient, ServerApiVersion } = require('mongodb');
const { body, validationResult } = require('express-validator');
const { title } = require('process');
const app = express(),
{ engine } = require('express-handlebars'),
bodyParser = require('body-parser');
app.set('view engine', 'hbs');
app.use(express.static("public"));
app.use(express.json({ extended: false }));
//app.use(bodyParser({ extended: false }))
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.engine('handlebars', engine({
defaultLayout: 'main'
}))
app.set('view engine', 'handlebars')
async function readingFromForm() {
console.log('data download has started');
console.log('3');
app.post('/added', function(sReq, sRes) {
var newTitle = sReq.body.title;
console.log('title:', newTitle);
var newAuthor = sReq.body.author;
console.log('author:', newAuthor);
var newMood = sReq.body.mood;
console.log('mood:', newMood);
var newTime = sReq.body.time;
console.log('time:', newTime);
var newDate = sReq.body.date;
console.log('date:', newDate);
sRes.sendStatus(200);
console.log(sReq); //Caution! It generates a lot of "spam" in the console !!!
console.log(sRes); //Caution! It generates a lot of "spam" in the console !!!
});
console.log('4');
console.log('data has been downloaded');
}
async function main() {
const uri = "mongodb+srv://rafal:rafal#cluster0.gsf4h.mongodb.net/cattu?retryWrites=true&w=majority";
const client = new MongoClient(uri);
try {
console.log('START');
console.log('1');
await client.connect(); // Connect to the MongoDB cluster
console.log('2');
await readingFromForm();
console.log('5');
await createListing(client, {
title: "newTitle",
author: "newAuthor",
mood: "newMood",
time: "newTime",
date: "newDate" // YYYY-MM-DD
})
console.log('END');
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
main().catch(console.error);
async function createListing(client, newListing) {
const result = await client.db("cattu").collection("test1").insertOne(newListing);
console.log(`New listing created with the following id: ${result.insertedId}`);
}
app.listen(port);
code in public/index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Cattu</title>
<link rel="stylesheet" href="styl.css">
<link rel="icon" type="image/x-icon" href="favicon.png">
</head>
<body>
<ul>
<li>Start</li>
<li>Formularz</li>
</ul>
<div id="poraDnia">
<div id="bgchange">
<div class="main">
<form method="POST" action="/added">
Podaj tytuł piosenki<br>
<input type="text" id="tytul" name="title" size="20px" required><br><br> Podaj wykonawcę<br>
<input type="text" id="wykonawca" name="author" size="20px" required><br><br> W jakim Jesteś nastroju?
<br>
<input type="checkbox" id="wesoly" value="wesoly" name="mood">
<label for="wesoly"> Wesoły/a </label><br>
<input type="checkbox" id="smutny" value="smutny" name="mood">
<label for="smutny"> Smutny/a </label><br>
<input type="checkbox" id="znudzony" value="znudzony" name="mood">
<label for="znudzony"> Znudzony/a </label><br>
<input type="checkbox" id="zmeczony" value="zmeczony" name="mood">
<label for="zmeczony"> Zmęczony/a </label><br>
<input type="checkbox" id="zdenerwowany" value="zdenerwowany" name="mood">
<label for="zdenerwowany"> Zdenerwowany/a </label><br>
<input type="checkbox" id="radosny" value="radosny" name="mood">
<label for="radosny"> Radosny/a </label><br>
<input type="checkbox" id="neutralny" value="neutralny" name="mood">
<label for="neutralny"> Neutralny/a </label><br>
<br>
<label for="pora"> Podaj porę dnia </label><br>
<select name="time" id="pora" required>
<option value="rano">Rano</option>
<option value="poludnie">Południe</option>
<option value="wieczor">Wieczór</option>
<option value="noc">Noc</option>
<option value="nie_pam">Nie pamiętam</option>
</select><br><br>
<label for="pora"> Podaj datę </label><br>
<input name="date" type="date"><br><br>
<button type="submit" class="submit">Skończone!</button>
<button type="reset" class="submit">Resetuj!</button>
</form>
</div>
<div class="content">
<div id="tlo3" onmouseover="rotatemoon(this)" onmouseout="rotatemoonB(this)">
<div id="obiekt_glowny3" onmouseover="movein(this)" onmouseout="moveout(this)">
<div id="ksiezyc_srodek"></div>
</div>
</div>
<div id="tloGwiazdy1">
<div id="gwiazda1"></div>
<div id="gwiazda2"></div>
<div id="gwiazda3"></div>
</div>
<div id="tloGwiazdy2">
<div id="gwiazda11"></div>
<div id="gwiazda12"></div>
<div id="gwiazda13"></div>
</div>
<div id="tlo2">
<div id="obiekt_glowny2" onmouseover="bigSun(this)" onmouseout="smolSun(this)">
<div id="promien1"></div>
<div id="promien2"></div>
<div id="promien3"></div>
<div id="promien4"></div>
<div id="promien5"></div>
<div id="promien6"></div>
<div id="promien7"></div>
<div id="promien8"></div>
<div id="promien9"></div>
<div id="promien0"></div>
</div>
</div>
<div id="tlo1">
<div id="obiekt_glowny1">
<div id="slonce" onmouseover="blouClounds(this)" onmouseout="whiteClounds(this)">
<div id="promien11"></div>
<div id="promien12"></div>
<div id="promien13"></div>
<div id="promien14"></div>
</div>
</div>
<div id="chmura1"></div>
<div id="chmura2"></div>
</div>
</div>
<div class="info1">
<br><br><br><br><br><br><br><br><br>Zobacz pełną historię
</div>
<div class="info2">
<!-- Tutaj chcemy pobierać dane z bazy żeby móc je wyświetlić (pobierać może zewnętrzny skrypt) -->
*Dane pobrane z bazy*
</div>
</div>
</div>
<script src="script1.js"></script>
</body>
</html>
I think you need to understand client-server communication, server should be ready to handle request whenever client made,
You may update your readingFromForm function to call createListing like
async function readingFromForm(client) {
console.log('data download has started');
console.log('3');
app.post('/added', async function(sReq, sRes) {
var bodyData = sReq.body;
await createListing(client, bodyData);
sRes.sendStatus(200);
// sReq is an request object contains all request related information(data, objects & functions)
// sRes is an response object contains all response related information(data, objects & functions)
});
console.log('4');
console.log('data has been downloaded');
}
and in the main function, you need to pass client object to readingFromForm function like
// await readingFromForm();
await readingFromForm(client);
use on click event handler in form. It will only submit the form when submit event will occur.
use onsubmit in form tag and an event handler in js.

TypeError: Cannot read property 'xxx' of undefined jQuery

I am trying to send a post request from site to server which includes user input data. I am getting TypeError: Cannot read property 'vehicle' of undefined as a response here.
HTML and script data:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Car Finder</title>
<link rel="stylesheet" href="style.css">
<center><h1>Craigslist Vehicle Finder</h1></center>
</head>
<body>
<form class="form">
<input type="text" name="vehicle" value="" id="vehicle">
<label for="vehicle">Vehicle</label>
</form>
<form class="form">
<input type="text" name="miles" value="" id="miles">
<label for="miles">Miles</label>
</form>
<label class="container">
<input type="checkbox" id="checkbox">
<span class="checkmark"></span>
<label for="checkbox">Manual</label>
</label>
<select id="select" class="City">
<option value="null">Select Location</option>
</select>
</div>
<form class="submit Search">
<input type="submit" value="Search Craigslist"><br/>
</form>
<script>
var select = document.getElementById("select"),
arr = ["atlanta","austin","boston","chicago","dallas","denver","detroit","houston","lasvegas","losangeles","miami","minneapolis","newyork","newhaven","orangecounty","philadelphia","phoenix","portland","raleigh","sacramento","san diego","seattle","sfbay","washingtondc"];
for(var i = 0; i < arr.length; i++) {
var option = document.createElement ("OPTION"),
txt = document.createTextNode(arr[i]);
option.appendChild(txt);
select.insertBefore(option, select.lastChild);
}
</script>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
<script>
$.post('http://localhost:3000', { vehicle: 'input#vehicle', miles: 'input#miles', location: 'select' }, function (err, result) {
if (err) {
console.log(err);
} else {
return data;
}
});
</script>
</body>
</html>
Server side method to receive the POST data:
app.post('/', (req, res, err) => {
if (req.method == 'POST') {
console.log(req.body.vehicle)
console.log(req.body.miles)
console.log(req.body.location)
}
})
using express server btw
There is an npm module called body-parser that extracts form data and sends that data to the req.body object. Using this module, you will be able to access form elements by name, in this case req.body.vehicle in your route handlers which should solve the issue. May be worth checking out the documentation:
https://www.npmjs.com/package/body-parser
EDIT: So I gave this a try using body-parser and got req.body printing out form contents in route handler. Hope this helps :)
app.js (Express code)
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(express.static(__dirname));
var urlencodedParser = bodyParser.urlencoded({ extended: false });
app.get('/', function(req, res) {
res.sendFile('index.html');
});
app.post('/findvehicle', urlencodedParser, function (req, res, err) {
console.log(req.body.vehicle);
console.log(req.body.miles);
console.log(req.body.location);
res.redirect('index.html');
});
app.listen("2000");
index.html
<form class="form" method="post" action="/findvehicle" >
<input type="text" name="vehicle" value="" id="vehicle">
<label for="vehicle">Vehicle</label>
<input type="text" name="miles" value="" id="miles">
<label for="miles">Miles</label>
<input type="checkbox" name="location" id="option1" value="Atlanta" autocomplete="off" checked=""> Atlanta
<input type="checkbox" name="location" id="option2" value="Austin" autocomplete="off"> Austin
<label for="miles">Location</label>
<input type="submit" value="Search Craigslist"><br/>
</form>

How could I get data for angular from handlebars when the page is rendered

I render the handlebars template with data.
var express = require('express'),
app = express();
var handlebars = require('express3-handlebars')
.create({
defaultLayout:'main',
helpers: {
section: function (name, options) {
if(!this._sections) this._sections = {};
this._sections[name] = options.fn(this);
return null;
}
}
});
// setup hbs
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.use(express.static(__dirname + '/public'));
app.use(function (req,res,next) {
next();
});
// serving homepage
app.get('/', function (req, res) {
res.render('home');
});
app.get('/about', function(req, res){
res.render('about', {
lucky: "you are lucky."
});
});
// 404
app.use(function(req, res, next){
res.status(404);
res.render('404');
});
// 500
app.use(function(err, req, res, next){
console.error(err.stack);
res.status(500);
res.render('500');
});
// startup
app.listen(3000, function() {
console.log('Express started on http://localhost:' +
app.get('port') + '; press Ctrl-C to terminate.');
});
In the client end, I use anuglarjs. How could I get the data 'lucky' at the page is open and handover to angular?
<div class="container" ng-app="myApp" ng-controller="myCtrl">
<div class="row">
<div class="col-lg-12">
<form class="form-horizontal" role="form" ng-submit="update()">
<div class="form-group">
<label class="col-md-2 control-label">Luck</label>
<div class="col-md-4">
<input type="text" class="form-control" name="Lucky"
ng-model="Lucky" value='{{lucky}}'/>
</div>
</div>
<div class="form-group">
<div style="padding-left:300px">
<input type="submit" value="Submit" class="btn btn-primary"/>
</div>
</div>
</form>
</div>
</div>
</div>
In the angular app, I want to handle the data to deal with something.
var myApp = angular.module('myApp', []);
myApp.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
myApp.controller('myCtrl', function ($scope) {
$scope.update= function () {
$scope.lucky = 'hello world, lucky guy!';
};
});
The value is set 'you are lucky.'. But it doesn't show. I searched some simliar question. They say it is confilct with data binding.
How to fix it?
First, you don't need to set the value attribute, however if you really need to use it should be just value="{{lucky}}" (without single quotes).
The main problem is that your ngModel is Lucky when it should be just lucky.
Here's a working demo based on your code:
(function() {
'use strict';
angular
.module('myApp', [])
.controller('myCtrl', myCtrl);
myCtrl.$inject = ['$scope'];
function myCtrl($scope) {
$scope.lucky = 'initial value';
$scope.update = function() {
$scope.lucky = 'hello world, lucky guy!';
};
}
})();
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body>
<div class="container" ng-app="myApp" ng-controller="myCtrl">
<div class="row">
<div class="col-lg-12">
<form class="form-horizontal" role="form" ng-submit="update()">
<div class="form-group">
<label class="col-md-2 control-label">Luck</label>
<div class="col-md-4">
<input type="text" class="form-control" name="Lucky" ng-model="lucky">
</div>
</div>
<div class="form-group">
<div style="padding-left:300px">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>

Sending Form Data to the Sever using AngularJS/NodeJS

I want to send form Data from my HTML/AngluarJS page by POST to the server (NodeJS), When submit I'm getting 400 (Bad request)
HTML Page that uses ng-submit:
<div class="container start" ng-controller="adminController">
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-body"><h1>Administration</h1>
<!-- form -->
<form class="form-signin" ng-submit="submit()" ng-controller="adminController">
<h2 class="form-signin-heading">Add new Bird</h2>
<select name= "tagType" id= "inputTag" class="form-control" placeholder="Tag Type" ng-modal="bird.tagType">
<option ng-repeat="tag in tags" value="{{option.id}}">{{tag.tagName}}</option>
</select><br/>
<button class="btn btn-primary" ng-click="addTag()">Add Tag</button>
<br/><br/>
<select name = "specie" id= "inputSpecie" class="form-control" placeholder="Specie Category" ng-modal="bird.specie">
<option ng-repeat="specie in species" value="{{option.id}}">{{specie.latinName}}</option>
</select>
<br/>
<button class="btn btn-primary" ng-click="addSpecie()">Add Specie</button>
<br/><br/>
<input type="text" id="inputSex" class="form-control" placeholder="Sex" ng-modal="bird.sex"/>
<br/><br/>
<input type="text" id="inputRFID" class="form-control" placeholder="RFID Value" ng-modal="bird.rfid"/>
<br/><br/>
<textarea id="inputComment" class="form-control" placeholder="Comment" ng-modal="bird.comment"></textarea>
<br/><br/>
<input type="file" ng-model="form.file_avatar" id="file_avatar" />
<br/><br/>
<input class="btn btn-lg btn-primary btn-block" type="submit" id="submit" value="Submit" />
</form>
</div>
</div>
My Controller Script
angular.module('test').controller('adminController', function($scope, $http)
{
$http.get('/api/adminPanel').then(function (response) {
// create a blank object to handle form data.
$scope.bird = {};
$scope.species = response.data.species;
$scope.tags = response.data.tags;
$scope.submit = function()
{
console.log(" Get fields values and Insert in the DB !");
// posting Data to server
$http.post('/api/adminPanel/create', {'bird': $scope.bird}).then(function (response) {
// sucess post
});
// failure post
}
});
});
Database script (adminPanel.js)
router.post('/create', function(req, res, next) {
var specie = req.body.specie;
var comment = req.body.comment;
var sex = req.body.sex;
// var birdSpecie = req.body.specie;
// console.log(" the Bird specie is " + birdSpecie);
console.log('the post request: ' + JSON.stringify(req.body));
database.addAnimal(specie,sex,comment).then(function()
{
res.sendStatus(200);}
,next);
});
your controller should be something like
angular.module('test').controller('adminController', function($scope, $http){
$scope.bird = {};
$scope.submit = function() {
$http.post('/api/adminPanel/create', $scope.bird).then(function (response) {
console.log(response);// as you need
});
};
});
and your server side should be:
router.post('/api/adminPanel/create', function(req, res, next) {
var specie = req.body.specie;
var comment = req.body.comment;
var sex = req.body.sex;
// your rest of code
return res.status(200).send("success") // return 200 and success message
});

CRUD edit with JayData and AngularJs

I am trying to create a basic CRUD application using JayData, AngularJS and OData Web Api. I have got so far as creating a List view and an Edit view and when clicking on the Edit option for an item in the List view it successfully redirects to the Edit view and it is populated as expected. However, when I go back to the List view and select subsequent Edit options, the Edit view does not get populated. Here is my relevant Angular code :
EDIT : Here is my complete code, as requested :
app.js :
var app = angular.module("app", ["localization", "ngResource", "ngRoute", "jaydata"]).
config(function ($routeProvider, $locationProvider) {
$routeProvider.
when('/Admin/Fixtures/List', { controller: FixtureListController, templateUrl: '/Content/Templates/Fixtures.html' }).
when('/Admin/Fixtures/Add', { controller: FixtureAddController, templateUrl: '/Content/Templates/FixtureAddEdit.html' }).
when('/Admin/Fixtures/Edit/:fixtureId', { controller: FixtureEditController, templateUrl: '/Content/Templates/FixtureAddEdit.html' }).
otherwise({ controller: TeamListController, redirectTo: 'Admin/Teams/List', templateUrl: '/Content/Templates/Teams.html' });
$locationProvider.html5Mode(true); //will use html5 mode rather than hashbang where available
});
var FixtureListController = function ($scope, $data) {
$scope.fixtures = [];
$scope.context = [];
$scope.selectedFixture = null;
$data.initService('http://lovelyjubbly.cloudapp.net/odata')
.then(function (context) {
$scope.context = context;
$scope.fixtures = context.Fixtures.include('Stage').include('HomeTeam').
include('AwayTeam').include('City').toLiveArray();
});
$scope.delete = function () {
//get id, can use this to get item from ng-repeat
var emp = new lovelyjubblyWebApi.Models.Fixture({ FixtureId: this.fixture.FixtureId });
$scope.context.Fixtures.remove(emp);
$scope.context.saveChanges();
};
};
//crud controllers
var FixtureAddController = function ($scope, $data) {
$scope.fixtures = [];
$data.initService('http://lovelyjubbly.cloudapp.net/odata')
.then(function (context) {
$scope.context = context;
$scope.fixtures = context.Fixtures.toLiveArray();
$scope.teams = context.Teams.toLiveArray();
$scope.cities = context.Cities.toLiveArray();
$scope.stages = context.Stages.toLiveArray();
});
$scope.save = function () {
//prevents a separate post
$scope.fixture.entityState = $data.EntityState.Modified;
$scope.context.Fixtures.add($scope.fixture, true);
$scope.context.saveChanges();
//reset state
$scope.context.stateManager.reset();
};
};
var FixtureEditController = function ($scope, $data, $routeParams) {
$scope.context = [];
$scope.fixtures = [];
$scope.teams = [];
$scope.cities = [];
$scope.stages = [];
$scope.selectedFixture = null;
$scope.fixture = null;
$data.initService('http://lovelyjubbly.cloudapp.net/odata')
.then(function (context) {
$scope.context = context;
$scope.fixtures = context.Fixtures.include('Stage').include('HomeTeam').
include('AwayTeam').include('City').toLiveArray();
$scope.teams = context.Teams.toLiveArray();
$scope.cities = context.Cities.toLiveArray();
$scope.stages = context.Stages.toLiveArray();
var emp = new lovelyjubblyWebApi.Models.Fixture({ FixtureId: $routeParams.fixtureId });
$scope.context.Fixtures.filter('FixtureId', '==', $routeParams.fixtureId)
.forEach(function (item) {
emp.StageId = item.StageId;
emp.CityId = item.CityId;
emp.FixtureDate = item.FixtureDate;
emp.HomeTeamId = item.HomeTeamId;
emp.HomeTeamScore = item.HomeTeamScore;
emp.AwayTeamId = item.AwayTeamId;
emp.AwayTeamScore = item.AwayTeamScore;
}).then(function (e)
{
$scope.fixture = emp;
});
$scope.save = function () {
if ($scope.form.$valid) { //check for valid form
var todo = $scope.context.Fixtures.attachOrGet({ FixtureId: $routeParams.fixtureId });
todo.StageId = $scope.fixture.StageId;
todo.CityId = $scope.fixture.CityId;
//emp2.FixtureDate = $scope.fixture.FixtureDate;
todo.FixtureDate = "10/10/2014 00:00";
todo.HomeTeamId = $scope.fixture.HomeTeamId;
todo.HomeTeamScore = $scope.fixture.HomeTeamScore;
todo.AwayTeamId = $scope.fixture.AwayTeamId;
todo.AwayTeamScore = $scope.fixture.AwayTeamScore;
$scope.context.saveChanges();
} else {
alert("invalid form");
}
};
});
};
List view:
<table class="table table-striped table-condensed table-hover">
<thead>
<th>
Fixture Id
</th>
<th>
Fixture Date
</th>
<th>
Stage
</th>
<th>
City
</th>
<th>
Home Team
</th>
<th>
Score
</th>
<th>
Away Team
</th>
<th>
Score
</th>
</thead>
<tbody>
<tr ng-repeat="fixture in fixtures | orderBy:'FixtureId'" id="fixture_{{fixture.FixtureId}}">
<td>{{fixture.FixtureId}}</td>
<td>{{fixture.FixtureDate}}</td>
<td>{{fixture.Stage.StageName}}</td>
<td>{{fixture.City.CityName}}</td>
<td>{{fixture.HomeTeam.TeamName}}</td>
<td>{{fixture.HomeTeamScore}}</td>
<td>{{fixture.AwayTeam.TeamName}}</td>
<td>{{fixture.AwayTeamScore}}</td>
<td>
<i class="glyphicon glyphicon-edit"></i>
<a ng-click="delete()"><i class="glyphicon glyphicon-remove"></i></a>
</td>
</tr>
</tbody>
</table>
Add/Edit view :
<form name="form" class="col-xs-2" id="form" class="form-horizontal">
<div class="control-group" ng-class="{error: form.StageName.$invalid}">
<label class="control-label" for="StageName">Stage Team</label>
<div class="controls">
<select class="form-control" ng-model="fixture.StageId" ng-options="stage.StageId as stage.StageName for stage in stages" required>
<option style="display:none" value="">Select</option>
</select>
<span ng-show="form.StageName.$dirty && form.StageName.$error.required">Stage required</span>
</div>
</div>
<div class="control-group" ng-class="{error: form.CityName.$invalid}">
<label class="control-label" for="CityName">City</label>
<div class="controls">
<select class="form-control" ng-model="fixture.CityId" ng-options="city.CityId as city.CityName for city in cities" required>
<option style="display:none" value="">Select</option>
</select>
<span ng-show="form.CityName.$dirty && form.CityName.$error.required">City required</span>
</div>
</div>
<div class="control-group" ng-class="{error: form.FixtureDate.$invalid}">
<label class="control-label" for="BirthDate">Fixture Date</label>
<div class="controls">
<input type='text' class="form-control" ng-model="fixture.FixtureDate" name='FixtureDate' title="FixtureDate" />
</div>
</div>
<div class="control-group" ng-class="{error: form.HomeTeamName.$invalid}">
<label class="control-label" for="HomeTeamName">Home Team</label>
<div class="controls">
<select class="form-control" ng-model="fixture.HomeTeamId" ng-options="team.TeamId as team.TeamName for team in teams" required>
<option style="display:none" value="">Select</option>
</select>
<span ng-show="form.HomeTeamName.$dirty && form.HomeTeamName.$error.required">Home Team required</span>
</div>
</div>
<div class="control-group" ng-class="{error: form.HomeTeamScore.$invalid}">
<label class="control-label" for="HomeTeamScore">Home Team Score</label>
<div class="controls">
<input type="text" class="form-control" placeholder="Score" ng-model="fixture.HomeTeamScore" id="HomeTeamScore" name="HomeTeamScore" />
</div>
</div>
<div class="control-group" ng-class="{error: form.AwayTeamName.$invalid}">
<label class="control-label" for="AwayTeamName">Away Team</label>
<div class="controls">
<select class="form-control" ng-model="fixture.AwayTeamId" ng-options="team.TeamId as team.TeamName for team in teams" required>
<option style="display:none" value="">Select</option>
</select>
<span ng-show="form.AwayTeamName.$dirty && form.AwayTeamName.$error.required">Away Team required</span>
</div>
</div>
<div class="control-group" ng-class="{error: form.AwayTeamScore.$invalid}">
<label class="control-label" for="AwayTeamScore">Away Team Score</label>
<div class="controls">
<input type="text" class="form-control" placeholder="Score" ng-model="fixture.AwayTeamScore" id="AwayTeamScore" name="AwayTeamScore" />
</div>
</div>
<br />
<div class="form-actions">
<button ng-show="form.$valid" ng-click="save()" class="btn btn-primary">{{action}}</button>
Cancel
</div>
</form>
This is a little tricky as we do not see the code for making a selection, routes, or how the controllers are invoked.
However, I believe that only one instance of the FixtureEditController is being created. You can test this by adding a breakpoint or console log to FixtureEditController.
Therefore, the call to:
$data.initService('http://lovelyjubbly.cloudapp.net/odata')
and
var emp = new lovelyjubblyWebApi.Models.Fixture({ FixtureId: $routeParams.fixtureId });
are only made once.
In the edit controller. you will want to detect when the route param changes so you can take action.
$scope.routeParams = $routeParams;
$data.initService('http://lovelyjubbly.cloudapp.net/odata')
.then(function (context) {
$scope.$watch('$routeParams',function(routeParams){
// this should run on any change in routeParams (regardless of the current state)
},true);
I am not certain that watching routeParams is the best approach, if the edit controller is inheriting from the list controller then you could watch "selectedFixture".

Categories

Resources