Disable form/page until APIs that load controls are complete - angularjs

I have an HTML form that makes use of a select element. The options of the select element are populated via an API call. I am finding that at times the page appears to be done loading but the select element is not yet populated. I am looking for a way to disable the page or indicate that it is not finished loading until the select element is populated from the API.
I have a single controller that handles the population of the select element as well as the Submit button click event which submits the form data to the back-end API. Below is my Angular and a snippet of the HTML that contais the select element.
HTML
<select ng-model="self.form.UserName"
ng-options="user.Name as user.Name for user in self.userList"
ng-required="true">
<option value="">- Choose User -</option>
</select>
Angular
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller('myAppController', function ($scope, $http) {
var self = this;
self.userList= [];
$http({
method: 'GET',
url: 'https://myApi.local/api/users/getAllUsers',
headers : {
'Content-Type': 'application/json'
}
}).then(function(result) {
self.userList= result.data;
}, function (error) {
console.log(error);
});
self.submitFormData = function() {
// form data submission handled here
}
});
</script>
Would this be a good use of ng-cloak to hide the entire page?

I would lay my call out more like this to get the finally block. I would have a spinner on the page show and block the user from touching anything behind it while it was going. This way, the user knows the page is still loading and cannot interact with the unpopulated drop-down.
$scope.showSpinner = true;
$http({
method: 'GET',
url: 'https://myApi.local/api/users/getAllUsers',
headers : {
'Content-Type': 'application/json'
}
}).then(function(result) {
self.userList= result.data;
}).error(function (error) {
console.log(error);
}).finally(function(){
$scope.showSpinner = false;
});

Related

AngularJS $http PUT request

I am buiding a CRUD apps with AngularJS and Django REST API.
I have created get and post method successfully but not getting how to put request. i tried stackoverflow lots of problem and youtube but i couldnt sort it out.
my current controller is:
app.controller('crudCtrl', function($scope, $http) {
$http.get("http://127.0.0.1:8000/api/v1/contact/?format=json")
.then(function(response) {
$scope.contacts = response.data; //this is get method that displayed all the list of contact
});
$scope.formModel = {}; // this is same input.js, it is POST method to to send data to database
$scope.onSubmit = function () {
console.log("hey, i am submitting");
console.log($scope.formModel);
$http.post('http://127.0.0.1:8000/api/v1/contact/', $scope.formModel).
success(function (data) {
console.log(":)");
}).error(function (data) {
console.log(":(");
});
};
$scope.selectUser = function (contact) {
console.log(contact); // it will select the data exactly where you click
$scope.clickedUser = contact;
};
$scope.updateUser = function (argument) { // it will get the form editable exactly which contact you clicked
};
});
and my edit view is, when i click on edit buttion, the form will be appear:
<form>
<input type="text" ng-model="clickedUser.userid">
<input type="text" ng-model="clickedUser.name">
<input type="text" ng-model="clickedUser.email">
<input type="text" ng-model="clickedUser.phone">
<button type="submit" ng-click="updateUser()" data-dismiss="modal">Submit</button>
</form>
Point to be noted, the edit form working nice on client side but it doesnt send the data to backend/API/Database.
can anyone tell me how can i do $http.put request? i tried w3school, youtube, and stackoverflow problem.
i got huge solution but i couldnt solve it.
this is my api endpoint for anything: http://127.0.0.1:8000/api/v1/contact/ so if i want to update particular field, i have to go through this url: http://127.0.0.1:8000/api/v1/contact/1 in the end of the url is id
I hope it is clear to you
You can try this as well
$http({method: "PUT", url: URL}).
then(
function(response) {
}, function(response) {
});
Can you just use angular put?
See: https://docs.angularjs.org/api/ng/service/$http#put
var clientData = {
text: "Put this somewhere"
};
$http.put( url, clientData ).then( function( serverResponse ) {
console.log(serverResponse);
},( error )=>{
console.log(serverError);
});

Angular-js $scope variable is not updated in view

I am new to angular-js and building a simple to-do application. I am creating a task and displaying the created task in a html table using ng-repeat. But the problem is that after posting the data, $scope.tasks variable is updated on controller side, but not in view. The view updates after refreshing the web page only and the task is added to html table. How can I make the view update after creating the task. Thanks in advance. Here is my code:
In my controller:
var app = angular.module('MyApp', ['ngMaterial', 'ngMessages']);
app.controller('DemoCtrl', function($scope,$mdSidenav,$mdDialog,$interval,$http,$mdToast) {
$scope.tasks = [];
_refreshTaskData(); //initial refresh
$scope.submitForm = function() {
var description = "";
var taskId = "";
$scope.formData = {
taskId: $scope.taskId,
description: $scope.description,
};
$http({
method: "POST",
url: 'savetask',
data: angular.toJson($scope.formData),
headers : {
'Content-Type': 'application/json',
}
}).then(_success, _error);
};
function _refreshTaskData() {
$http({
method : 'GET',
url : 'getTask',
}).then(function(res) { // success
$scope.tasks = res.data;
}, function(res) { // error
console.log("Error: " + res.status + " : " + res.data);
});
}
function _success(res) {
$mdDialog.hide();
console.log('in success function');
_refreshTaskData(); ;
}
function _error(res) {
//error handling
}
});
In my view:
<table>
<tr ng-repeat=" t in tasks">
<td>{{t.id}}</td>
<td>{{t.description}}</td>
</tr>
</table>
You must understand that these JS frameworks are asynchronous. Now what happens is, if you do an API call and make another API call whose result is based on the first one, the console does not wait for the result from one API and directly moves forward. SO what's happening in your case is sometimes/many times, before the POST call is served, the controller is not able to get fresh data with GET in time, thus not updating the view. What you can possibly do is enforce the GET only when POST is served
$http({
method: "POST",
url: 'savetask',
data: angular.toJson($scope.formData),
headers : {
'Content-Type': 'application/json',
}
}).then(function(res){
$http({
method : 'GET',
url : 'getTask',
}).then(function(res) { // success
$scope.tasks = res.data;
}, function(err) { // error
console.log("Error: " + err.status + " : " + err.data);
});
});
It would be best if you are sending a success message from the backend and checking before GET call
I think you are not calling _refreshEmployeeData at any point of time. If you add that instead of _refreshTaskData in your JS, then you will be able to see the result in view.
Also kindly use ng-init to call the _refreshEmployeeData in the controller. That would be the best way to initialize the fields.

Select element value not being sent with other form elements in Angular

I am using Angular to submit the contents of a form to an API endpoint. Everything worked fine until I tried to change one of the text input fields to a select dropdown. I am using ng-options to populate the select drop down but when I go to send the form contents to the API endpoint the value of the select element is not sent. Below is the HTML (with class and styling information removed for brevity) and the Angular.
HTML
<form ng-submit="self.addNewEmployee()" novalidate>
<input ng-model="self.form.employeeName" type="text">
<select ng-model="self.form.department" ng-options="dept.name as dept.Name for dept in self.departmentList">
</select>
<input ng-model="self.form.salary" type="text" />
<input id="btnSubmit" type="submit" value="Add Employee" />
</form>
Angular
<script type="text/javascript">
var adminToolApp = angular.module('adminToolApp', []);
adminToolApp .controller('AdminToolController', function ($scope, $http) {
var self = this;
self.departmentList = [];
// Gets all departments to populate select input
$http({
method: 'GET',
url: 'https://api.myServer.net/api/getAllDepartments',
headers : {
'Content-Type': 'application/json',
}
}).then(function(result) {
self.departmentList = result.data;
}, function (error) {
console.log(error);
});
// Submits form data to add new employee
self.addNewEmployee = function() {
return $http({
method: 'POST',
url: 'https://api.myServer.net/api/addNewEmployee',
data: angular.toJson(self.form),
headers: {
'Content-Type': 'application/json',
}
}).then(_submissionSuccess, _submissionFailure);
};
// Private methods
function _submissionSuccess(response) {
self.submissionResults = response.data;
};
function _submissionFailure(response) {
self.submissionResults = 'An error occured: ' + response.status;
};
});
</script>
When I inspect the payload sent to the API two of the form elements are present (employeeName and salary) however department is not present. I defined self.form.department as the ng-model for the select element, why is it not submitted as part of the form collection?
Try change this
ng-options="dept.Name as dept.Name for dept in self.departmentList">

How can i use the data gotten from a json response in another html file using angular js

I have different html pages, after a user logs in, i have different data been sent back, and i will have to use some of this data together with my next post to a url in another html page.
for instance, if a user should log in, if the user is been authenticated, i will get the userid, sex, and some other data to be used in another page, since i have to send everything together with it on the other activity.
Doing something like Bundle or SharedPreferences in JAVA
This is the code for my login page
<script>
var app = angular.module('myapp', [])
app.controller('empcontroller', function($scope, $http){
$scope.insertdata=function(){
console.log("triggered");
$http({
method: 'POST',
url: "myurl",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {username: $scope.fname, pswd: $scope.lname}
})
.success(function(data, status, headers, config) {
var mssg = data.MESSAGE;
iqwerty.toast.Toast(mssg);
console.log(data);
if ( data.RESULT === 1) {
window.location.href = 'homes.html';
} else {
$scope.errorMsg = "Login not correct";
}
})
.error(function(data, status, headers, config) {
$scope.errorMsg = 'Unable to submit form';
})
}});</script>
This is the result i get in my console log{"RESULT":1,"MESSAGE":"SUCCESSFUL","EMPID":"2223444"}
How can i use my data (that's the result i get as a response after my request has been sent to a given url) in another html page (angularjs controller..which is in another html file). and how can i use this same username in another html page..because, i am to send the username and the EMPID together..in my other html page
Try building a Single page application using angular.js. You can easily share data between different states, controllers using rootScope,factory etc.

change Content-type to "application/json" POST method, RESTful API

I am new at AngularJS and I needed your help.
All I need just need is to POST my json to the API and recieve the proper response.
Here's my JSON where i don't know where to code this.
JSON
{
"userId" :"testAgent2",
"token" :"testAgent2",
"terminalInfo":"test2",
"forceLogin" :"false"
}
NOT SURE IF I'm doing this right.
CONTROLLER.JS
function UserLoginCtrl($scope, UserLoginResource) {
//Save a new userLogin
$scope.loginUser = function() {
var loggedin = false;
var uUsername = $scope.userUsername;
var uPassword = $scope.userPassword;
var uforcelogin = 'true';
UserLoginResource.save();
}
}
SERVICES.JS
angular.module('UserLoginModule', ['ngResource'])
.factory('UserLoginResource', function($resource, $http) {
$http.defaults.useXDomain = true;
delete $http.defaults.headers.common['X-Requested-With'];
$http.defaults.headers.post["Content-Type"] = "application/json"; //NOT WORKING
return $resource('http://123.123.123.123\\:1234/SOME/LOCATION/THERE', {}, {
save: {
method:'POST',
headers: [{'Content-Type': 'application/json'}]
} //NOT WORKING EITHER
});
});
INDEX.HTML
<html ng-app>
<head>
<script src="js/lib/angular/angular.js"></script>
<script src="js/lib/angular/angular-resource.js"></script>
</head>
<body ng-controller="UserLoginCtrl">
<form class="form-horizontal" name="form-horizontal" ng-submit="loginUser();">
<div class="button-login">
<!-- start: button-login -->
<button class="btn btn-primary" type="submit">Login</button>
</div>
</form>
</body>
</html>
I kept on getting a response like Unsupported Media Type. I don't know, what else to do.
Assuming you are able to use one of the more recent "unstable" releases, the correct syntax to change the header is.
app.factory('BarService', function ($resource) {
var BarService = $resource('/foo/api/bars/:id', {}, {
'delete': {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
}
});
return BarService;
});
I find the $resource service is a tremendously powerful tool for building applications and has matured to a point that you do not need to fall back to $http as much. Plus its active record like patterns are damn convenient.
Posting a JSON object is quite easy in Angular. All you need to do is the following:
Create a Javascript Object
I'll use your exact properties from your code.
var postObject = new Object();
postObject.userId = "testAgent2";
postObject.token = "testAgent2";
postObject.terminalInfo = "test2";
postObject.forceLogin = "false";
Post the object to the API
To post an object to an API you merely need a simple $http.post function. See below:
$http.post("/path/to/api/", postObject).success(function(data){
//Callback function here.
//"data" is the response from the server.
});
Since JSON is the default method of posting to an API, there's no need to reset that. See this link on $http shortcuts for more information.
With regards to your code specifically, try changing your save method to include this simple post method.
The right way to set 'Content-Type': 'application/json' is setting a transformRequest function for the save action.
angular.module('NoteWrangler')
.factory('NoteNgResource', function NoteNgResourceFactory($resource) {
// https://docs.angularjs.org/api/ngResource/service/$resource
return $resource("./php/notes/:id", {}, {
save : { // redefine save action defaults
method : 'POST',
url : "./php/notes", // I dont want the id in the url
transformRequest: function(data, headers){
console.log(headers);
headers = angular.extend({}, headers, {'Content-Type': 'application/json'});
console.log(headers);
console.log(data);
console.log(angular.toJson(data));
return angular.toJson(data); // this will go in the body request
}
}
});
});
It seems there isn't a method to clear query parameters, the request will have both...

Resources