How do I refresh ng-repeat after an Angular Update - angularjs

Using the code below, I am able to add items in my database, but the table showing the current entries doesn't update (I thought Angular did that automatically?) --- How do I force a refresh of the data?
.controller("addItemsController", function ($scope, $http) {
var url = _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('MyContacts')/items";
var vm = $scope;
var requestDigest = $("#__REQUESTDIGEST").val()
vm.addContact = function () {
return $http({
headers: { "accept": "application/json; odata=verbose", "X-RequestDigest": requestDigest, "content-Type": "application/json;odata=verbose" },
method: "POST",
url: url,
data: {
'Title': vm.LastName,
'FirstName': vm.FirstName,
"__metadata": { "type": "SP.Data.MyContactsListItem" }
}
})
.then(saveContact)
.catch(function (message) {
console.log("addContact() error: " + message);
});
function saveContact(data, status, headers, config) {
alert("Item Added Successfully");
return data.data.d;
}
}
})
NOTE: I tried using $scope.contacts.push(data) as suggested elsewhere in the forum, but contacts came back undefined (?!)

Related

Accessing API with $http POST Content-Type application/x-www-form-urlencoded always gets 'false' results

I have the following REST Service which I have to access on POST Method,
I can access it via jQuery but I don't know how to do it with AngularJS (v1)
<string xmlns = "http://schemas.microsoft.com/2003/10/Serialization/">
<script id = "tinyhippos-injected" />
{
"volumeResult": {
"gyydt": "9771241.17704773",
"gytotal": "29864436.1770477",
"gybudgeted": "29864436.1770477",
"lyydt": "10197350",
"lytotal": "27859381",
"lybudgeted": "10197350",
"cyytd": "6992208",
"lastUpdate": "March-2017"
},
"valueResult": {
"gyydt": "26862094",
"gytotal": "68217952",
"gybudgeted": "68232952",
"lyydt": "0",
"lytotal": "0",
"lybudgeted": "0",
"cyytd": "68217952",
"lastUpdate": "March-2017"
},
"trucksResult": {
"gyydt": "165951",
"gytotal": "497879",
"gybudgeted": "497879",
"lyydt": "168822",
"lytotal": "468814",
"lybudgeted": "168822",
"cyytd": "119442",
"lastUpdate": "March-2017"
}
}
</string>
Here is my controller.js:
angular.module('starter.controllers', [])
.controller('DashCtrl', ['$scope', '$http', function ($scope, $http) {
$http({
//headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
headers: {'Content-Type' : 'application/json'},
url: 'https://myurl../api/getHPData',
method: 'POST',
// data: data,
params: {
"stationId": 263,
"crusherId": 27,
"monthYear": '2016-04'
}
})
.then(function (response) {
console.log(response);
})
// I don't have to use .success and .error function as they are [depricated][2]
//.success(function (data, status, headers, config) {
// $scope.greeting = data;
// var Result = JSON.stringify(data);
// var Result = JSON.parse(data);
//})
//.error(function (error, status, headers, config) {
// console.log("====================== Error Status is: " + error);
// console.log("====================== Status is: " + status);
// console.log("====================== Error occured");
//})
}]) // eof controller DashCtrl
.controller('MapsCtrl', function($scope) {})
.controller('AccountCtrl', function($scope) {
$scope.settings = {
enableFriends: true
};
});
What I want is value of:
"volumeResult" > "gytotal"
Problems:
It always return:
Object {data: "{"result":"false"}", status: 200, config: Object, statusText: "OK", headers: function}
and
When I pass monthYear without quotes it process (arithmetic) it as (2016-04 = 2012)
As the service is POST but when I analyze it in Chrome Developers Tool so I get: (Query String, which isn't meant to be POST)
ionic.bundle.js:25005
XHR finished loading: POST
"https://myurl../api/getHPData?crusherId=27&monthYear=2016-4&stationId=263"
Possible solutions:
Either I am using wrong header:
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': 'application/json'
},
Or header may be,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
Or as per my friend says:
When I change your code to use the code above, I get this error:
"{"Message":"The requested resource does not support http method
'OPTIONS'."}" Which means that there is a CORS (Cross-origin Resource Sharing) issue. Chrome is trying to make a "preflight" request to allow
CORS, but the server doesn't know what to do with it.
But I don't think it is because of this as I am receiving:
Object {data: "{"result":"false"}", status: 200, config: Object,
statusText: "OK", headers: function}
from server. Noted that: {"result":"false"} is the message displayed by the server when it didn't find data or you pass wrong parametes. Also bellow jQuery code is proof that I can access the server. :)
Edit
jQuery Snippet:
<script>
$(document).ready(function() {
get_homepage_data(263, 27, '2016-04');
function get_homepage_data(stationIds, crusherIds, date) {
var url = "https://myurl..";
var data_to_send = {
'stationId': stationIds,
'crusherId': crusherIds,
'monthYear': date
};
console.log("Value is: " + JSON.stringify(data_to_send));
//change sender name with account holder name
// console.log(data_to_send)
$.ajax({
url: url,
method: 'post',
dataType: 'json',
//contentType: 'application/json',
data: data_to_send,
processData: true,
// crossDomain: true,
beforeSend: function () {
}
, complete: function () {}
, success: function (result1) {
// I know I can do it in one line but lazy enough to edit it here :p
var Result = JSON.parse(result1);
var value_data = Result["valueResult"];
var foo = value_data["gyydt"];
console.log("Log of foo is: " + foo);
var foo2 = 0;
// 10 lac is one million.
foo2 = foo / 1000000 + ' million';
console.log(JSON.stringify(value_data["gyydt"]) + " in million is: " + foo2);
}
, error: function (request, error) {
return false;
}
});
}
}); // eof Document. Ready
</script>
Output of above script is script is:
Value is: {"stationId":263,"crusherId":27,"monthYear":"2016-04"}
XHR finished loading: POST "https://myurl../api/getHPData".
Log of foo is: 26862094
"26862094" in million is: 26.862094 million
Which is indeed perfect. :)
try to use $http this way ..
$http.post("https://myurl../..",JSON.stringify({
stationId: 263,
crusherId: 27,
monthYear:'2016-04'
})).then(function(res){
console.log(res);
}).catch(function(errors){
console.log(errors);
})
I got answer. Whao.
Thank you georgeawg for his answer:
He says:
When posting form data that is URL encoded, transform the request with the $httpParamSerializer service:
$http({
headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
url: 'https://myurl..',
method: 'POST',
transformRequest: $httpParamSerializer,
transformResponse: function (x) {
return angular.fromJson(angular.fromJson(x));
},
data: {
"stationId": 263,
"crusherId": 27,
"monthYear": '2016-04'
}
})
.then(function(response) {
console.log(response);
$scope.res = response.data;
console.log($scope.res);
});
Normally the $http service automatically parses the results from a JSON encoded object but this API is returning a string that has been doubly serialized from an object. The transformResponse function fixes that problem.
Now I am able to get value of gytotal as:
var myData = parseFloat(response.data.valueResult.gytotal);
console.log(myData);

how to write different post method in angularjs?

i' using AngularJS v1.4.2. i have 2 html page , they have 2 controller.both controller have save event. how to use use http post method
first controller i'm calling post method given below
var promisePost = crudService.post(Countries);
promisePost.then(function (pl) {
alert("Sucessfully Inserted")
getCountry();
$stateParams.country = "";
}, function (err) {
alert("NOt Inserted")
});
second controller i'm calling post method given below
var promisePost = crudService.post(Levels);
promisePost.then(function (pl) {
alert("Sucessfully Inserted")
getLevel();
}, function (err) {
alert("NOt Inserted")
});
my app.js
myapp.service('crudService', function ($http, RESOURCES) {
//Create new record
this.post = function (Country) {
var request = $http({
method: "post",
url: RESOURCES.baseUrl + "saveCountry",
data: Country
});
return request;
}
this.post = function (Level) {
var request = $http({
method: "post",
url: RESOURCES.baseUrl + "saveLevel",
data: Level
});
return request;
}
});
but this code only take last post method.How to selecet post method properly. Anyone can helpme?
User countryPost and levelPost as follows and call those accordingly.
myapp.service('crudService', function ($http, RESOURCES) {
//Create new record
this.countryPost= function (Country) {
var request = $http({
method: "post",
url: RESOURCES.baseUrl + "saveCountry",
data: Country
});
return request;
}
this.levelPost= function (Level) {
var request = $http({
method: "post",
url: RESOURCES.baseUrl + "saveLevel",
data: Level
});
return request;
}
});
The best practice for using services is to return an object from it
myapp.factory('crudService', function ($http, RESOURCES) {
return {
saveCountry : function(){
return $http({
method: "post",
url: RESOURCES.baseUrl + "saveCountry",
data: Country
});
},
saveLevel : function(){
return $http({
method: "post",
url: RESOURCES.baseUrl + "saveLevel",
data: Level
});
}
}
});
then inject it into your controller dependencies and use it like :
crudService.saveLevel().then(function(){
//do some code here
})
Create a single post method instead and receive the url to call in it as parameter along with the data. As shown below:
this.post = function (data, remainingUrl) {
var request = $http({
method: "post",
url: RESOURCES.baseUrl + remainingUrl,
data: data
});
return request;
}

Unable to get JSON from asmx Web Service in AngularJS

I am unable to parse a json file from a asmx webservice.
Here is my WebMethod:
[WebMethod]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public void GetDataJSON()
{
//var dt = GetCubeResult("");
var _DbConn = Helper.GetDBConnection();
var _CubeConn = Helper.GetCubeConnection();
var _query = Helper.GetWebConfig("dashboard_config");
Data[] datArray = new Data[1];
Data data = GetTilesAsDataArray(_query, _DbConn);
datArray[0] = data;
System.Web.Script.Serialization.JavaScriptSerializer serializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
Context.Response.Clear();
Context.Response.ContentType = "application/json";
/*
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type,Accept,Origin,X-Requested-With");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
*/
Context.Response.Write(serializer.Serialize(datArray));
}
and here is my AngularJS Code
app.controller('jsonServerBox', ['$scope', '$http', function($scope, $http) {
$http({
method: 'POST',
crossDomain: true,
contentType: "application/json; charset=utf-8",
url: 'myasmx.asmx/getjson',
data: '[]',
dataType: 'json',
xhrFields: {
withCredentials: true
},
cache: 'false',
headers: {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Content-Type': 'application/json; charset=utf-8'
}
//url: 'serverbox.json'
}).success(function (data) {
//var myjson = JSON.parse(data);
//$scope.ocw = myjson;
//$scope.ocw = JSON.parse(data);
$scope.ocw = data;
$scope.loading = false;
})
.error(function(data, status) {
console.error('Repos error', status, data);
//alert("schlecht");
});}]);
I already try it with parse and other methods, but no one is working - is there any error in my webservice ? with a local json file the angular code is working.
EDIT: Its working now. I changed my angular Code to following:
app.controller('jsonServerBox', ['$scope', '$http', function($scope, $http) {
$http.get("myasmx.asmx/get",
{
params: {
format: "json",
cache: "false"
}
})
.success(function(data){
$scope.ocw = data;
console.log($scope.ocw);
});}]);
But sometimes the browser show it, sometimes not - why is that ? And in IE10 it is not working - no support in ie 10 ?

AngularJS: Pass data from Controller to Service

First: Here is a plunk.
Currently I am trying to build a basic sign-up app with AngularJS hosted on a SharePoint site. I am pulling the current user data with a factory like so:
app.factory('Data', function ($http, $log) {
return {
getCurrentUser: function (complete, failure) {
jQuery.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/currentUser",
type: "GET",
dataType: "json",
headers: {
"Accept": "application/json;odata=verbose"
},
success: function (data) {
complete(data.d);
},
error: function (data) {
failure(data);
}
});
}
I then use a controller to assign the results (in this case the user Title) to a value:
app.controller('IndexCtrl', function ($scope, Data) {
Data.getCurrentUser(function (user) {
CurrentUser = user.Title;
});
Now, the issue I am having is that the value of CurrentUser is not usable in all parts of the factory. Right now, everything is in one factory and one controller. So, I can use CurrentUser to create a new appointment like this:
app.factory('Data', function ($http, $log) {
return {
updateAppointment: function (appointment) {
var Title = appointment.Title;
var Appointment = appointment.Appointment;
var CurrentSpots = appointment.Openings;
var Id = appointment.Id;
// Create new Reservations list item
jQuery.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/getByTitle('SharePointList')/Items",
type: "POST",
data: JSON.stringify({
"__metadata": { type: "SP.Data.SharePointListItem" },
Title: Title,
Appointment: Appointment,
Colleague: CurrentUser,
AppointmentId: Id
}),
headers: {
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
},
success: function (data, textStatus, jqXHR) {
},
failure: function (jqXHR, textStatus, errorThrown) {
var response = JSON.parse(jqXHR.responseText);
var message = response ? response.error.message.value : textStatus;
alert("Error: " + message);
}
});
But I cannot seem to use it when I try to do a query including that CurrentUser value in something like this:
app.factory('Data', function ($http, $log) {
return {
getCurrentAppointment: function (successCallback) {
$http({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/getByTitle('SharePointList')/Items?$filter=User eq '" + CurrentUser + "'",
method: "GET",
dataType: "json",
async: "true",
headers: {
"Accept": "application/json;odata=verbose"
}
})
.success(function (data, status, headers, config) {
successCallback(data.d.results);
})
.error(function (data, status, headers, config) {
$log.warn(data, status, headers, config);
});
}
No matter what I've tried, it consistently gives me an undefined return for that CurrentUser value. Any help would be appreciated. Thank you in advance!
You don't demonstrate where you are declaring CurrentUser (eg var CurrentUser;) (I couldnt see it).
I trust you are not using a global variable (evil).
Also it is unclear where you are invoking these factory methods that are accessing CurrentUser. You are assigning CurrentUser inside the Data.getCurrentUser invocation in your controller. Assuming you have declared CurrentUser outside that function somewhere, it will not be assigned until the asynchronous request has completed. I'd suggest refactoring your method updateAppointment to receive the CurrentUser parameter instead of relying on outside scope.

$http post in Angular.js

I've just started learning Angular.js. How do I re-write the following code in Angular.js?
var postData = "<RequestInfo> "
+ "<Event>GetPersons</Event> "
+ "</RequestInfo>";
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState == 4 || req.readyState == "complete") {
if (req.status == 200) {
console.log(req.responseText);
}
}
};
try {
req.open('POST', 'http://samedomain.com/GetPersons', false);
req.send(postData);
}
catch (e) {
console.log(e);
}
Here's what I have so far -
function TestController($scope) {
$scope.persons = $http({
url: 'http://samedomain.com/GetPersons',
method: "POST",
data: postData,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function (data, status, headers, config) {
$scope.data = data; // how do pass this to $scope.persons?
}).error(function (data, status, headers, config) {
$scope.status = status;
});
}
html
<div ng-controller="TestController">
<li ng-repeat="person in persons">{{person.name}}</li>
</div>
Am I in the right direction?
In your current function if you are assigning $scope.persons to $http which is a promise object as $http returns a promise object.
So instead of assigning scope.persons to $http you should assign $scope.persons inside the success of $http as mentioned below:
function TestController($scope, $http) {
$http({
url: 'http://samedomain.com/GetPersons',
method: "POST",
data: postData,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function (data, status, headers, config) {
$scope.persons = data; // assign $scope.persons here as promise is resolved here
}).error(function (data, status, headers, config) {
$scope.status = status;
});
}
Here is a variation of the solution given by Ajay beni. Using the method then allows to chain multiple promises, since the then returns a new promise.
function TestController($scope) {
$http({
url: 'http://samedomain.com/GetPersons',
method: "POST",
data: postData,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function(response) {
// success
},
function(response) { // optional
// failed
}
);
}
use $http:
AngularJS: API: $http
$http.post(url, data, [config]);
Implementation example:
$http.post('http://service.provider.com/api/endpoint', {
Description: 'Test Object',
TestType: 'PostTest'
}, {
headers {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json;odata=verbose'
}
}
).then(function (result) {
console.log('Success');
console.log(result);
}, function(error) {
console.log('Error:');
console.log(error);
});
Lets break this down: Url is a little obvious, so we skip that...
data: This is the body content of your postman request
{
Description: 'Test Object',
TestType: 'PostTest'
}
config: This is where we can inject headers, event handlers, caching... see AngularJS: API: $http: scroll down to config Headers are the most common postman variant of http that people struggle to replicate in angularJS
{
headers {
'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
'Accept': 'application/json;odata=verbose'
}
}
Response: the $http actions return an angular promise, I recommend using .then(successFunction, errorFunction) to process that promise see AngularJS: The Deferred API (Promises)
.then(function (result) {
console.log('Success');
console.log(result);
}, function(error) {
console.log('Error:');
console.log(error);
});

Resources