I have two controllers and setup a service to hold the data:
var myApp = angular.module('myApp', []);
myApp.factory('Data', function() {
return { message: "This is a message from a service", Type: "This is a type from a service" }
});
function FirstCtrl($scope, Data) {
$scope.data = Data;
}
function SecondCtrl($scope, Data) {
$scope.data = Data;
}
In my HTML, I have inputs to bind these values:
<div ng-controller="FirstCtrl">
<input type="text" ng-model="data.message">
<h1>{{ data.message }}</h1>
</div>
<div ng-controller="SecondCtrl">
<input type="text" ng-model="data.type">
<h1>{{ data.type }}</h1>
</div>
However, all im getting back from the service is my data.message and nothing for data.type.
Why is this?
It is a simple type error. The Factory returns a Data object with 'Type' as a key. In your HTML you have used 'type' as the key instead of 'Type'.
Related
I am a newbie of angularjs using version 1.6.4. I am using this module leon/angular-upload for upload functionality, minify version. On successful upload request, server return json object of uploaded file information on onSuccess(response) function as you can see in my user-registration.template.html file. Now i need to take this json object to my controller so that i can save this information in my database. Below is the few lines of my code.
user-registration.template.html:
<form role="form">
<div class="form-group float-label-control">
<label>Name</label>
<input type="text" placeholder="Name" class="form-control" ng-model="model.user.name">
</div>
<!-- leon/angular-upload -->
<div upload-button
url="/user_uploads"
on-success="onSuccess(response)"
on-error="onError(response)">Upload</div>
<div class="text-center">
<button type="button" class="btn btn-default" ng-click="model.save(model.user)">Save</button>
</div>
</form>
My component "user-registration.component.js":
(function(){
"use strict";
var module = angular.module(__appName);
function saveUser(user, $http){
var url = user.id > 0 ? __apiRoot + "/users/" + user.id : __apiRoot + "/users";
var dataObj = {
payload: JSON.stringify(user),
_method: "PUT"
}
return $http.post(url, dataObj);
}
function controller($http){
var model = this;
model.user = null;
model.save = function(user){
console.log(JSON.stringify(user));
saveUser(user, $http).then(function(response){
alert(response.data.msg);
});
}
}
module.component("userRegistration", {
templateUrl: "components/user-registration/user-registration.template.html",
bindings: {
value: "<"
},
controllerAs: "model",
controller: ["$http", controller]
});
}());
Try to put your server response data to rootScope model for Exempel :
$rootScope.serveResponse = response ;
and with this rootScope you can share your variable data between controller
Here is my RestController Class
#RestController
#RequestMapping(value="/user")
public class Test {
#RequestMapping(value="/{userEmailId}",method=RequestMethod.GET)
public ModelAndView getUser(#PathVariable("userEmailId") String userEmailId){
//something goes here and get User class object
ModelAndView mav=new ModelAndView("showuser");
mav.addObject("user", user);//user is User class object
return mav;
}
}
I want to display this user object in showuser.jsp using Angular JS How can I do that?
Below is sample example assuming your user object have firstname and lastname:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
</head>
<div ng-app="myApp" ng-controller="userController">
<form action="demo_form.html">
First name: <input type="text" name="fname" ng-model="fname"><br>
Last name: <input type="text" name="lname" ng-model="lname"><br>
</form>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('userController', function($scope, $http) {
$http({
method : "GET",
url : "/user/xyz#a.com"
}).then(function mySucces(response) {
$scope.fname = response.fname;
$scope.lname = response.lname;
}, function myError(response) {
//handling error
});
});
</script>
When my page loads, all the items in my mongo db are displayed. I have a form to input new entries, or delete entries. When creating or deleting, the http process works, but the new data is not updated in the DOM.
Most of the related questions I have researched suggest to make sure my ng-controller wraps the entire body, which it does. Other's suggest to use $apply, but I've also read that this is wrong. When I try it, I am alerted "in progress" anyway.
My only guess is that after the http request, a new scope is loaded and angular doesn't pick up on that. Or for some reason its just not reloading the data after my request. Here is my code, thanks for your help.
index.html
<body ng-controller="MainController">
<!-- list records and delete checkbox -->
<div id="record-list" class="row">
<div class="col-sm-4 col-sm-offset-4">
<!-- loop over records in $scope.records -->
<div class="checkbox" ng-repeat="record in records">
<label>
<input type="checkbox" ng-click="deleteRecord(record._id)">
{{ record.artist}} - {{ record.album }} - {{ record.bpm}}
</label>
</div>
</div>
</div>
<!-- record form data -->
<div id="record-form" class="row">
<div class="col-sm-8 col-sm-offset-2 text-center">
<form>
<div class="form-group">
<input type="artist" class="form-control input-lg text-center" placeholder="Artist" ng-model="formData.artist">
</div>
<div class="form-group">
<input type="album" class="form-control input-lg text-center" placeholder="Album" ng-model="formData.album">
</div>
<div class="form-group">
<input type="bpm" class="form-control input-lg text-center" placeholder="BPM" ng-model="formData.bpm">
</div>
<button type="submit" class="btn btn-primary btn-lg" ng-click="createRecord()">Add</button>
</form>
</div>
</div>
</div>
controller.js
angular.module('myApp', []).controller('MainController', ['$scope', '$http', function ($scope, $http) {
$scope.formData = {};
$scope.sortType = 'artist';
$scope.sortReverse = false;
//$scope.searchRecords = '';
$http.get('/api/records/')
.success(function(data) {
$scope.records = data;
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
$scope.createRecord = function() {
$http.post('/api/records/', $scope.formData)
.success(function(data) {
//$scope.formData = {};
$scope.records = data;
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
$scope.deleteRecord = function(id) {
$http.delete('/api/records/' + id)
.success(function(data) {
$scope.records = data;
console.log("delete record scope: " + data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
}])
Your controller JS looks fine - I would say from looking at this that you need to export the updated values from your mongoDB collection when the POST/DELETE is successful.
If you use Mongoose (mongoDB plugin), you can update your API code to send back the updated data upon success with something like this:
// POST
// --------------------------------------------------------
// Provides method for saving new record to the db, then send back list of all records
app.post('/api/records', (req, res) => {
// Creates a new record based on the Mongoose Schema
const newRecord= new Record(req.body);
// New record is saved to the db
newRecord.save((err) => {
// Test for errors
if(err) res.send(err);
// Now grab ALL data on records
const all = Records.find({});
all.exec((err, records) => {
// Test for errors
if(err) res.send(err);
// If no errors are found, it responds with JSON for all records
res.json(records);
});
});
});
ngResource in factory works fine but unfortunately the result able to select JSON index. At the same time it is possible to bind the same $scope.resultItems variable
Console log appear like this 👇
Not working from ngResource http://codepen.io/anon/pen/dMbRXx
Working fine from variable http://codepen.io/anon/pen/ONLgNX
var app = angular.module('app', ['ngResource']);
app.controller('myCtrl', function($scope, categoryFilter) {
$scope.resultItems = categoryFilter.query();
$scope.resultIndex = $scope.resultItems[0];
$scope.resultIndexItem = $scope.resultItems[0].status;
});
app.factory('categoryFilter', function($resource) {
return $resource("https://maps.googleapis.com/maps/api/geocode/json?address=NY", {}, {
query: {
method: "GET"
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-resource/1.5.0/angular-resource.min.js"></script>
<div class="container" ng-app="app" ng-controller="myCtrl">
<div class="col-xs-12">
<h3>ngResource result</h3>
<pre>{{resultItems | json }}</pre>
<hr />
<pre>{{resultIndex | json }}</pre>
<hr />
<pre>{{resultIndexItem | json}}</pre>
</div>
</div>
Each resource in fact is a ajax request that means it is asynchronous, So you have to use callbacks to query function. Then your code looks like this
var app = angular.module('app', ['ngResource']);
app.controller('myCtrl', function($scope, categoryFilter) {
categoryFilter.query(function(results){
$scope.resultItems = results;
$scope.resultItems.results[0];
$scope.resultIndexItem = $scope.resultItems.status;
});
});
app.factory('categoryFilter', function($resource) {
return $resource("https://maps.googleapis.com/maps/api/geocode/json?address=NY", {}, {
query: {
method: "GET"
}
});
});
link
Update
Sorry If I miss read you question, All items in json within {} will be an object can be accessed using ., For example in json results and status is object and items represented in [] is an array and they can be accessed using index.
From json
I'm working on building a little app that accepts input from a form (the input being a name) and then goes on to POST the name to a mock webservice using $httpBackend. After the POST I then do a GET also from a mock webservice using $httpBackend that then gets the name/variable that was set with the POST. After getting it from the service a simple greeting is constructed and displayed back at the client.
However, currently when the data gets displayed now back to the client it reads "Hello undefined!" When it should be reading "Hello [whatever name you inputed] !". I used Yeoman to do my app scaffolding so I hope everyone will be able to understand my file and directory structure.
My app.js:
'use strict';
angular
.module('sayHiApp', [
'ngCookies',
'ngMockE2E',
'ngResource',
'ngSanitize',
'ngRoute'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
})
.run(function($httpBackend) {
var name = 'Default Name';
$httpBackend.whenPOST('/name').respond(function(method, url, data) {
//name = angular.fromJson(data);
name = data;
return [200, name, {}];
});
$httpBackend.whenGET('/name').respond(name);
// Tell httpBackend to ignore GET requests to our templates
$httpBackend.whenGET(/\.html$/).passThrough();
});
My main.js:
'use strict';
angular.module('sayHiApp')
.controller('MainCtrl', function ($scope, $http) {
// Accepts form input
$scope.submit = function() {
// POSTS data to webservice
setName($scope.input);
// GET data from webservice
var name = getName();
// Construct greeting
$scope.greeting = 'Hello ' + name + ' !';
};
function setName (dataToPost) {
$http.post('/name', dataToPost).
success(function(data) {
$scope.error = false;
return data;
}).
error(function(data) {
$scope.error = true;
return data;
});
}
// GET name from webservice
function getName () {
$http.get('/name').
success(function(data) {
$scope.error = false;
return data;
}).
error(function(data) {
$scope.error = true;
return data;
});
}
});
My main.html:
<div class="row text-center">
<div class="col-xs-12 col-md-6 col-md-offset-3">
<img src="../images/SayHi.png" class="logo" />
</div>
</div>
<div class="row text-center">
<div class="col-xs-10 col-xs-offset-1 col-md-4 col-md-offset-4">
<form role="form" name="greeting-form" ng-Submit="submit()">
<input type="text" class="form-control input-field" name="name-field" placeholder="Your Name" ng-model="input">
<button type="submit" class="btn btn-default button">Greet Me!</button>
</form>
</div>
</div>
<div class="row text-center">
<div class="col-xs-12 col-md-6 col-md-offset-3">
<p class="greeting">{{greeting}}</p>
</div>
</div>
At the moment your getName() method returns nothing. Also you cant just call getName() and expect the result to be available immediately after the function call since $http.get() runs asynchronously.
You should try something like this:
function getName () {
//return the Promise
return $http.get('/name').success(function(data) {
$scope.error = false;
return data;
}).error(function(data) {
$scope.error = true;
return data;
});
}
$scope.submit = function() {
setName($scope.input);
//wait for the Promise to be resolved and then update the view
getName().then(function(name) {
$scope.greeting = 'Hello ' + name + ' !';
});
};
By the way you should put getName(), setName() into a service.
You can't return a regular variable from an async call because by the time this success block is excuted the function already finished it's iteration.
You need to return a promise object (as a guide line, and preffered do it from a service).
I won't fix your code but I'll share the necessary tool with you - Promises.
Following angular's doc for $q and $http you can build yourself a template for async calls handling.
The template should be something like that:
angular.module('mymodule').factory('MyAsyncService', function($q, http) {
var service = {
getNames: function() {
var params ={};
var deferObject = $q.defer();
params.nameId = 1;
$http.get('/names', params).success(function(data) {
deferObject.resolve(data)
}).error(function(error) {
deferObject.reject(error)
});
return $q.promise;
}
}
});
angular.module('mymodule').controller('MyGettingNameCtrl', ['$scope', 'MyAsyncService', function ($scope, MyAsyncService) {
$scope.getName = function() {
MyAsyncService.getName().then(function(data) {
//do something with name
}, function(error) {
//Error
})
}
}]);