I am creating an application which will run queries on my store's database, based on what the user enters on the webpage. I have successfully created the backend method. And it successfully returns the response. But I am unable to retrieve the data and display it on my webpage in the form of a dynamic table. I am a bit new to AngularJS, so please bear with me, but any help is appreciated.
StoreController.java
#RequestMapping(value = "/runQuery", method = RequestMethod.GET)
public List<Map<String, Object>> runQuery(#RequestParam(value="query", defaultValue="* FROM items") String statement, Model model) {
List<Map<String, Object>> answer = storeService.executeUserQuery(statement);
model.addAttribute("resultList", answer);
return answer;
}
I tried to model my controller in such a way that it can dynamically take the data received from the Java controller and assign it to the $scope variable.
app.module.js
(function(){
'use strict';
angular.module('app', []);
})();
store.controller.js
angular
.module('app').controller('StoreController', ['$scope','StoreService','StoreController','$q', function ($scope,StoreService, StoreController, $q) {
$scope.runQuery = function () {
StoreService.runQuery($scope.statement)
.then (function (data){
$scope.rows = response.data;
$scope.cols = Object.keys($scope.rows[0]);
},
function error(response){
if (response.status == 404){
$scope.errorMessage = response.data[0];
}
else {
$scope.errorMessage = 'Error displaying result user!';
}
});
}
}
]);
app.service('StoreService',['$http', function ($http,$q) {
this.runQuery = function runQuery(statement){
return $http({
method: 'GET',
url: 'http://localhost:8080/runQuery/',
params: {statement:statement},
headers: 'Accept:application/json'
}).then( function(response){
return reponse.data;
});
}
index.html
<body data-ng-app="app" data-ng-controller="StoreController">
<div class="container">
<form th:action="#{/logout}" method="get">
<button class="btn btn-md btn-danger btn-block"
style="color: #fff; background-color: #e213a2; border-color: #c3c2c0;"
name="registration" type="Submit">Logout</button>
</form>
<div class="panel-group" style="margin-top: 40px">
<div class="panel panel-primary">
<div class="panel-heading">
<span th:utext="${userName}"></span>
</div>
<div>
<form name="queryForm" method="get" data-ng-submit="runQuery()">
<div class="panel-body">
<h3 id="queryLabel">Select Query:</h3>
<textarea id="query" wrap="soft"
placeholder="Please do not enter SELECT with your query, it's added automatically!!" data-ng-model="statement"></textarea>
<button type="submit">Run Query</button>
</div>
</form>
<div class="panel-body" id="results">
<h3 id="queryLabel">Result:</h3>
<table border="1">
<tr>
<th data-ng-repeat="column in cols">{{column}}</th>
</tr>
<tr data-ng-repeat="row in rows">
<td data-ng-repeat="column in cols">{{row[column]}}</td>
</tr>
</table>
</div>
</div>
<div>
<p class="admin-message-text text-center" th:utext="${adminMessage}"></p>
</div>
</div>
</div>
</div>
</body>
The table on the html page, works because I received it from this link
http://jsfiddle.net/v6ruo7mj/1/
But it's not populating the tables with the data received from my backend controller method. I do not have any entities as this is just querying an existing database, so I need not to add any entities.
The issue probably is this line here in the service callback within your controller:
.then (function (data){
$scope.rows = response.data;
// ...
}
try with:
.then (function (data){
$scope.rows = data;
// ...
}
You already return the responses data in your service when calling:
}).then( function(response){
return reponse.data;
});
Aside from your question I should mention that your Spring controller seems to be vunerable to SQL injection. It's in general not a good idea to allow the user to access your database directly. Although I don't know how your StoreService on the backend is implemented. But it seems as if an attacker could easily send a HTTP call to your endpoint and drop your database.
You have a typo in the runQuery function:
app.service('StoreService',['$http', function ($http,$q) {
this.runQuery = function runQuery(statement){
return $http({
method: 'GET',
url: 'http://localhost:8080/runQuery/',
params: {statement:statement},
headers: 'Accept:application/json'
}).then( function(response){
̶r̶e̶t̶u̶r̶n̶ ̶ ̶r̶e̶p̶o̶n̶s̶e̶.̶d̶a̶t̶a̶;̶
return response.data
});
}
}]);
Related
I used Spring framework as a back-end and angular as a front end. When I try to insert data from the angualrJs value is inserted into database but display error code. please suggest me what is the wrong in this code.
var app = angular.module("categoryApp", []);
app.controller('submitCategory', [ '$scope', '$http',
function($scope, $http) {
$scope.submitClick = function() {
var dataObj = {
name : $scope.name
};
var result = $http.post("/tutorials/category", dataObj);
result.success(function(data, status, headers, config) {
alert("success");
$scope.message = data;
});
result.error(function(data, status, headers, config) {
alert("failure message: " + JSON.stringify({
data : data
}));
});
$scope.name = '';
}
}
]);
And my html is
<body ng-app="categoryApp">
<section class="panel" ng-controller="submitCategory">
<header class="panel-heading"> Basic Forms </header>
<div class="panel-body">
<form role="form" method="post" ng-submit="submitClick()">
<div class="form-group">
<label for="category">Category</label> <input type="text"
class="form-control" id="exampleInputEmail1" name="name"
placeholder="Category" ng-model="name">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</section>
</body>
And my controller method is
#RequestMapping(value = "/category", method = RequestMethod.POST)
public ResponseEntity<String> postCategory(#RequestBody Category category,
Model model) {
categoryService.save(category);
return new ResponseEntity<String>("success", HttpStatus.OK);
}
The issue is caused by ResponseEntity<String> .Your code java should be like this:
#RequestMapping(value = "/category", method = RequestMethod.POST)
public ResponseEntity<String> postCategory(#RequestBody Category category,
Model model) {
categoryService.save(category);
return new ResponseEntity<String>("success", HttpStatus.OK); }
I am currently working on a small angularjs app which is basically a user profile management app.
The problem i am having is with adding users dynamically. When i enter the user data, it successfully POST's to my local server i have setup, BUT i have to refresh the page to see the new user in the users list
I obviously dont want to have to refresh.
-Yes i've tried $scope.apply() after running the POST function
Something i am noticing with Angular Batarang (Debugging tool), is that the scope is updating fine, but there is a blank spot or 'null' value where the new user should be.
Here are the Controllers:
UsersApp.controller('UserListController', [ '$scope', 'userService', function($scope, userService) {
$scope.usersList = userService.usersList;
$scope.users = userService.users;
$scope.user = userService.user;
}]);
UsersApp.controller('AddUserController', function($scope, $window, dataResources, userService) {
$scope.addNew = function addNew(newUser) {
$scope.usersList = userService.usersList;
var firstName = newUser.firstName;
var lastName = newUser.lastName;
var phone = newUser.phone;
var email = newUser.email;
$scope.newUserData = {
firstName , lastName, phone , email
}
new dataResources.create($scope.newUserData);
$scope.usersList.push(dataResources);
$scope.$apply();
};
And Here are my views:
Add User:
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src="js/minimize.js"></script>
<div ng-controller="AddUserController">
<div class="userInfo" id="usernameDiv">
<h2 id="username">User<img id="showhide" src="images/plus.png" style="position:absolute; padding-left:15px; width:31px; color:white;"></h2>
</div>
<div class="userInfo">
<div id="listInfo">
<form ng-controller="AddUserController">
<input type="text" placeholder= "First Name" ng-model="newUser.firstName"></input>
<input type="text" placeholder= "Last Name" ng-model="newUser.lastName"></input>
<input type="text" placeholder= "Phone Number" ng-model="newUser.phone"></input>
<input type="text" placeholder= "Email" ng-model="newUser.email"></input>
<button type="submit" ng-click="addNew(newUser)">Add User</button>
</form>
</div>
</div>
Users List:
<!DOCTYPE html>
<html>
<head></head>
<body id="">
<div ng-controller="UserListController">
<div class="userInfo">
<h2>List of Users</h2>
<div id="listInfo">
<ul style="list-style-type: none;">
<li ng-repeat="user in usersList">
<!--<p class="userData">ID: {{ user }}</p> -->
<p class="userData"><a style="cursor:pointer;" ui-sref="UserProfile">{{ user.firstName }}</a></p>
</li>
</ul>
</div>
</div>
Factory and Service:
UsersApp.factory('dataResources', [ '$resource', function($resource) {
return $resource('http://localhost:24149/users/:id', {}, {
query: {method:'GET', params:{idnum: '#id'}, isArray:true},
create: {method:'POST', headers: { 'Content-Type': 'application/json' }},
update: {method:'PUT', params:{idnum: '#id'}},
remove: {method:'DELETE', params:{idnum:'#id'}, isArray:true}
});
}]);
UsersApp.service('userService', function(dataResources) {
return {
usersList: dataResources.query()
}
});
I'm not sure if I follow exactly, but I believe you need to deal with a promise from your POST and then push the result. e.g.,
dataResources.create($scope.newUserData).$promise.then(function(data) {
$scope.usersList.push(data);
});
Your service will return a promise and then when the POST is complete your service should return the new user and you just add it to your current list.
See $resource documentation:
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
According to the doc your code should look like this:
dataResources.create($scope.newUserData,
function(data) {
$scope.usersList.push(data);
}
);
controller: you don't need to make a new userdata object, you can just use newUser
UsersApp.controller('AddUserController', function($scope, $window, dataResources, userService) {
$scope.usersList = userService.usersList;
$scope.addNew = function addNew(newUser) {
dataResources.create($scope.newUser,
function(data) {
$scope.usersList.push(data);
}
);
};
};
Same idea for angular2 using observables.
public posts: any;
onPost(input) {
this.dataService.jsonserverPost(input)
.subscribe(
(data: any) => {
this.posts.push(data);
}
);
}
I have the following code with an if statement depending if a user has saved an article or not. I'm simply trying to delete the article from the database using jquery. I unsure where im going wrong? help is much appreciated!
View:
<form action="{{URL::route('article-delete')}}" method="post" id="article_one_delete">
<div class="form-group">
<input type="hidden" name="first_desc" value="{{$firstrow->description}}" class="form-control">
</div>
<div class="form-group">
<input type="hidden" name="first_title" value="{{$firstrow->title1}}" class="form-control">
</div>
<button type ="button" id="Recodelete" class="btn btn-success btn-xs">UnSave</button>
{{Form::token()}}
</form>
Route:
Route::delete('/home/', array( 'as' => 'article-delete',
'uses' => 'HomeController#deletearticle'));
Controller:
public function deletearticle(){
$firsttitle = Input::get('first_title');
$articledelete = UserSaveArticle::where('user_id', Auth::id()
->where ('user_save_articles.chosen_title', $firsttitle))->delete();
return true;
JQuery:
$(document).ready(function(){
$('#Recodelete').on('click', function(){
var article_one_delete = $('#article_one_delete').serializeArray();
var url_d = $('#article_one_delete').attr('action');
$.get(url_d, article_one_delete, function(data){
console.log(data);
});
});
});
You should define right route for DELETE article, like this:
Route::delete('/article/{id}', ['as' => 'article-delete', 'uses' => 'HomeController#deleteArticle']);
In the HomeController $id variable (article ID) will be available as a method parameter:
function deleteArticle($id)
{
…
}
In PHP side you defined DELETE route, it means you should make DELETE request on JS side using the ajax method:
$.ajax({
url: '/article/' + articleId,
type: 'DELETE',
success: function(result) {
// Do something with the result
}
});
Ive built a rest-API to add todos in a mongodb. I can successfully save instances by using the following setup in postman:
http://localhost:3000/api/addtodo x-www-form-urlencoded with values text="Test", completed: "false".
Now when I try to replicate this with Angular, it doesnt work, the todo is saved but without the text and completed attributes, I cant seem to access the text or completed values from body. What am I doing wrong? Code below:
Angular-HTML:
<div id="todo-form" class="row">
<div class="col-sm-8 col-sm-offset-2 text-center">
<form>
<div class="form-group">
<!-- BIND THIS VALUE TO formData.text IN ANGULAR -->
<input type="text" class="form-control input-lg text-center" placeholder="I want to buy a puppy that will love me forever" ng-model="formData.text">
</div>
<!-- createToDo() WILL CREATE NEW TODOS -->
<button type="submit" class="btn btn-primary btn-lg" ng-click="createTodo()">Add</button>
</form>
</div>
</div>
Angular-js:
$scope.createTodo = function() {
$http.post('/api//addtodo', $scope.formData)
.success(function(data) {
$scope.formData = {}; // clear the form so our user is ready to enter another
$scope.todos = data;
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
REST-API:
router.post('/addtodo', function(req,res) {
var Todo = require('../models/Todo.js');
var todo = new Todo();
todo.text = req.body.text;
todo.completed = req.body.completed;
todo.save(function (err) {
if(!err) {
return console.log("created");
} else {
return console.log(err);
}
});
return res.send(todo);
});
$http.post sends it's data using application/json and not application/x-www-form-urlencoded. Source.
If you're using body-parser, make sure you've included the JSON middleware.
app.use(bodyParser.json());
Either that or change your default headers for angular.
module.run(function($http) {
$http.defaults.headers.post = 'application/x-www-form-urlencoded';
});
See solution below:
I'm trying to connect to a Parse.com Rest backend and display data from object values.
HTML (I put several angular calls to be sure to catch output):
<div ng-controller="MyController">
<p>{{item}}<p>
<p>{{items}}<p>
<p>{{item.firstName}}<p>
<p>{{data}}<p>
</div>
JAVASCRIPT rest:
function MyController($scope, $http) {
$scope.items = [];
$scope.getItems = function() {
$http({method : 'GET',url : 'https://api.parse.com/1/classes/Professional/id', headers: { 'X-Parse-Application-Id':'XXXX', 'X-Parse-REST-API-Key':'YYYY'}})
.success(function(data, status) {
$scope.items = data;
})
.error(function(data, status) {
alert("Error");
});
};
}
This won't work, it does strictly nothing, not even a message in the console.
I know the rest call got the correct credential, as I'm able to get object content returned when I test it with a rest tester program. Maybe the URL should not be absolute ?
Any clue is very welcome, i've spent DAYS on that.
SOLUTION:
Thanks to the help of people answering this thread, I was able to find the solution to this problem so I just wanted to contribute back:
Get Json object data from Parse.com backend, pass it authentification parameters:
function MyController($scope, $http) {
$scope.items = [];
$scope.getItems = function() {
$http({method : 'GET',url : 'https://api.parse.com/1/classes/Professional', headers: { 'X-Parse-Application-Id':'XXX', 'X-Parse-REST-API-Key':'YYY'}})
.success(function(data, status) {
$scope.items = data;
})
.error(function(data, status) {
alert("Error");
});
};
Notice that ' ' necessary arround header key object values. Those ' ' are not necessary around method and url keys.
Template that list all 'firstName' of each object:
<div ng-controller="MyController" ng-init="getItems()">
<ul>
<li ng-repeat="item in items.results"> {{item.firstName}} </li>
</ul>
</div>
Notice: "item in items.results". "results" is necessary because the return value is a JSON object that contains a results field with a JSON array that lists the objects. This could save you some headache.
Also notice "ng-init": if you don't put that, or any other form of call to the getItem(),then nothing will happen and you will be returned no error.
That was my first try of Angularjs, and i'm already in love ^^.
Based in your request the controller should be:
HTML
<div ng-controller="MyController">
<button type="button" ng-click="getItems()">Get Items</button>
<ul>
<li ng-repeat="item in items"> item.firstName </li>
</ul>
</div>
JS
function MyController($scope, $http) {
$scope.items = []
$scope.getItems = function() {
$http({method : 'GET',url : 'https://api.parse.com/1/classes/Users', headers: { 'X-Parse-Application-Id':'XXXXXXXXXXXXX', 'X-Parse-REST-API-Key':'YYYYYYYYYYYYY'}})
.success(function(data, status) {
$scope.items = data;
})
.error(function(data, status) {
alert("Error");
})
}
}
Just a little update to the newer versions of Angular (using .then since version 1.5):
myApp.controller('MyController', function($scope, $http) {
$scope.items = []
$http({
method: 'GET',
url: 'https://api.parse.com/1/classes/Users',
headers: {'X-Parse-Application-Id':'XXXXXXXXXXXXX', 'X-Parse-REST-API-Key':'YYYYYYYYYYYYY'}
})
.then(function successCallback(response) {
alert("Succesfully connected to the API");
$scope.items = data;
}, function errorCallback(response) {
alert("Error connecting to API");
});
});
var app = angular.module("app",[]);
app.controller("postcontroller", function($scope, $http){
$scope.getAllProjects = function() {
var url = 'https://reqres.in/api/products';
$http.get(url).then(
function(response) {
$scope.projects = response.data.data;
},
function error(response) {
$scope.postResultMessage = "Error with status: "
+ response.statusText;
});
}
$scope.getAllProjects();
});
<div ng-app="app">
<div ng-controller="postcontroller">
<div class="panel-body">
<div class="form-group">
<label class="control-label col-sm-2" for="project">Project:</label>
<div class="col-sm-5">
<select id="projectSelector" class="form-control">
<option id="id" ng-repeat="project in projects"
value="{{project.id}}">{{project.name}}</option>
</select>
</div>
</div>
</div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>