Angular forEach with comparison from json? - javascript

So I have an input field which fetches data from lets say json1.
On submit, I want that input value to be compared to data from json2 and do different stuff depending on the outcome, but I can't wrap my head around it since I can't break the forEach. My code is executing but winds through it all instead of stoping on corresponding if statement.
I've seen a couple of threads talking about using for-loop instead but no luck there either. Any ideas?
I would like something like this:
$scope.superButton = function() {
$http.get(superUrl)
.then(function(res) {
angular.forEach(res.data, function(item) {
// If supertag exists, add to it
if ($scope.id == item.tag.tag_id) {
console.log('yay, tag is now supertag');
$http({
method: 'PUT',
url: superUrl,
headers: {
'Content-Type': 'application/json'
},
data: {
'title': $scope.title,
'subtitle': $scope.subtitle,
'tag': {
'title': $scope.selected,
'tag_id': $scope.id
}
}
}).then(function(data, status, headers, config, statusText) {
console.log('added EXISTING supertag:' + data.statusText);
}).catch(function(err) {
console.log(err.data.message);
});
}
// If supertag doesn't exist, create it
else if ($scope.id != item.tag.tag_id) {
$http({
method: 'POST',
url: superUrl,
headers: {
'Content-Type': 'application/json'
},
data: {
'title': $scope.title,
'subtitle': $scope.subtitle,
'tag': {
'title': $scope.selected,
'tag_id': $scope.id
}
}
}).then(function(data, status, headers, config, statusText) {
console.log('added NEW supertag: ' + data.statusText);
}).catch(function(err) {
console.log(err.data.message);
});
}
// If
else {
console.log('no tags');
}
});
});
};

You can use JavaScript Array.prototype.filter() to validate if $http.get() response contains a supertag:
$scope.superButton = function() {
$http.get(superUrl)
.then(function(res) {
var len = res.data.filter(function(item) {
return $scope.id === item.tag.tag_id;
}).length,
method = (len) ? 'PUT' : 'POST',
segmentUrl = (len) ? '/' + $scope.id : '',
msg = (len) ? 'EXISTING supertag: ' : 'NEW supertag: ';
$http({
method: method,
url: superUrl + segmentUrl,
headers: {
'Content-Type': 'application/json'
},
data: {
'title': $scope.title,
'subtitle': $scope.subtitle,
'tag': {
'title': $scope.selected,
'tag_id': $scope.id
}
}
})
.then(function(data, status, headers, config, statusText) {
console.log(msg + data.statusText);
})
.catch(function(err) {
console.log(err.data.message);
});
});
};

Related

Angular not display data returned from $http

Very new to Angular.js and having an issue that I cannot figure out. This is my html
<user-details></user-details>
This is my angular code:
angular.
module('rtcTimesheet').
component('userDetails', {
template:
'<p>Hi {{$ctrl.username}}</p>',
controller: function UserDetailsController(globalDataService,$http) {
if(globalDataService.getServicePath()) {
try {
this.username="name here";
this.userId=""
$http({
method: 'GET',
url: globalDataService.getServicePath()+'login.php',
params: {
t: "log",
un: "username",
pwd: "123456789"
}
}).then(function(response){
if(response.data.hasOwnProperty("HasError")) {
$("#debug").append("<p>ERROR: " + response.data.ErrorMessage+"</p>");
} else {
username=response.data.name;
userId=response.data.id;
$("#debug").append(this.username);
}
},function (err){
$("#debug").append("ERROR http: "+err.status);
});
} catch(err) {
$("#debug").append("CATCH ERROR: "+err.status+"<br/>");
}
} else {
$("#debug").append("<p>Unable to get service path...</p>");
}
}
});
I know the data is being returned correctly, as I can output it using the
$("#debug").append(this.username)
When the page is loaded it just displays the initial 'name here'. Probably has something to do with the slight delay of getting the data back from the database, but no idea how to get around this?
Your variable referance is incorrect. Check the code bellow to use controllerAs refferance with _self.
angular.
module('rtcTimesheet').
component('userDetails', {
template:
'<p>Hi {{$ctrl.username}}</p>',
controller: function UserDetailsController(globalDataService,$http) {
if(globalDataService.getServicePath()) {
try {
var _self = this;
_self.username="name here";
_self.userId=""
$http({
method: 'GET',
url: globalDataService.getServicePath()+'login.php',
params: {
t: "log",
un: "username",
pwd: "123456789"
}
}).then(function(response){
if(response.data.hasOwnProperty("HasError")) {
$("#debug").append("<p>ERROR: " + response.data.ErrorMessage+"</p>");
} else {
_self.username=response.data.name;
_self.userId=response.data.id;
$("#debug").append(_self.username);
}
},function (err){
$("#debug").append("ERROR http: "+err.status);
});
} catch(err) {
$("#debug").append("CATCH ERROR: "+err.status+"<br/>");
}
} else {
$("#debug").append("<p>Unable to get service path...</p>");
}
}
});

Array empty after posting data from angular controler

I am using codeigniter and angular for my app. When I post the data from angular controller to CI controller, array seems to be empty (result of print_r is "array()") .Can someone tell me why?
Angular Part:
$scope.posaljiKontroleru = function () {
$scope.prosek = {kalorije: 0.0, proteini: 0.0, uh: 0.0, masti: 0.0};
$http({
method: 'POST',
url: 'http://localhost/psi/Pravljenjejela/dodajBazi',
data: $scope.prosek
}).then(function (res) {
$window.location.href = "http://localhost/psi/Pravljenjejela/dodajBazi";
}, function (err) {
console.log(err);
});
});
}
CI part
public function dodajBazi() {
$info = $this->input->post();
print_r($info);
}
You need to use default content-type header
Try this:
$http({
method: 'POST',
url: 'http://localhost/psi/Pravljenjejela/dodajBazi',
data: $scope.prosek,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function (res) {
$window.location.href = "http://localhost/psi/Pravljenjejela/dodajBazi";
}, function (err) {
console.log(err);
});

Http request configuration url must be a string. Received: undefined

I just moved my upload function from controller (where it was working as it should) to factory and it sudenly stopped working. I'm keep getting this error, but i don't know/understand where the problem is
angular.js:13550 Error: [$http:badreq] Http request configuration url must be a string. Received: undefined
http://errors.angularjs.org/1.5.5/$http/badreq?p0=undefined
at angular.js:68
at $http (angular.js:11194)
at uploadWithAngular (ng-file-upload.js:91)
at sendHttp (ng-file-upload.js:144)
at upload (ng-file-upload.js:330)
at Scope.$scope.uploadDocument (locationsCtrl.js:131)
at fn (eval at compile (angular.js:14432), <anonymous>:4:338)
at expensiveCheckFn (angular.js:15485)
at callback (angular.js:25018)
at Scope.$eval (angular.js:17229)
This is my upload document function in controller
$scope.uploadDocument = function(file) {
if($scope.documentName.length > 4) {
$scope.errorMsg = '';
file.upload = Upload.upload( documentsFactory.uploadDocument(
$scope.id_location,
$scope.documentName,
$scope.documentDescription,
file,
$scope.locationUniqueId
));
file.upload.then(function (response) {
$scope.documentName = $scope.documentDescription = $scope.userFile = '';
documentsFactory.getDocuments($scope.id_location).then(function (data) {
$scope.documents = data;
});
$timeout(function () {
file.result = response.data;
});
}, function (response) {
if (response.status > 0)
$scope.errorMsg = response.status + ': ' + response.data;
}, function (evt) {
// Math.min is to fix IE which reports 200% sometimes
file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
}else{
$scope.errorMsg = 'Name should be at least 5 chars long';
}
};
And this is my factory
factory.uploadDocument = function(id_location, name, description, file, locationUniqueId){
return $http({
method: 'POST',
url: $location.protocol() + '://' + $location.host() + '/rest/api/document/documents',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: {
id_location: id_location,
name: name,
description: description,
userFile: file,
locationUniqueId: locationUniqueId
}
}).then(function successCallback(response){
return response.data;
},function errorCallback(response){
console.log('Error uploading documents: ' + response);
});
};
UPDATE:
This is working example if i make "upload request" in my controller
file.upload = Upload.upload({
url: $location.protocol() + '://' + $location.host() + '/rest/api/document/documents/',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: {
id_location: $scope.id_location,
name: $scope.documentName,
description: $scope.documentDescription,
userFile: file,
locationUniqueId: $scope.locationUniqueId
}
});
If you need any additional inflammations please let me know and i will provide. Thank you in advance
Following the error stack:
From ng-file-upload repository.
this.upload = function (config, internal) {
which is called by you there
Upload.upload( documentsFactory.uploadDocument(
$scope.id_location,
$scope.documentName,
$scope.documentDescription,
file,
$scope.locationUniqueId
));
line 330
return sendHttp(config);
line 144
uploadWithAngular();
line 91
$http(config).then(function (r) {
Where the error gets thrown. It looks like Upload.upload doesn't accept a promise, but a config for the $http call.
EDIT
What about returning the config object?
factory.uploadDocument = function(id_location, name, description, file, locationUniqueId){
return {
method: 'POST',
url: $location.protocol() + '://' + $location.host() + '/rest/api/document/documents',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: {
id_location: id_location,
name: name,
description: description,
userFile: file,
locationUniqueId: locationUniqueId
}
}
};
The best idea would be to move Upload to the factory and return the promise.
factory.uploadDocument = function(id_location, name, description, file, locationUniqueId){
return Upload.upload({
method: 'POST',
url: $location.protocol() + '://' + $location.host() + '/rest/api/document/documents',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: {
id_location: id_location,
name: name,
description: description,
userFile: file,
locationUniqueId: locationUniqueId
}
});

What is the best way catch an error in the middle of a promise chain?

I have an Angular checkout validation process that has to pass certain async requests which send form information before allowing users to checkout.
I currently have all of the $.ajax calls firing on a .then() basis after the initial $.ajax function call. However, I am having an issue with catching an error in the middle of the promise chain.
In the code below, on the second promise call of .then($scope.sendShippingInformation) this is where I need to handle the error.
You see, the response gives me back a key value pair of response.extensionAttributes.errorMessage : 'error message here'; If there is an error on the form. I need to be able to alert said error to the user, and allow them to correct whatever form field they didn't enter correctly. Allow them to fix it, and process the information again.
I have tried adding the success: someFunctionHere as well as the error: someFunctionHere to no avail. Any help would be greatly appreciated.
// Initial $.ajax request
$scope.sendPaymentInformation = function() {
console.log('Send Billing Info');
var guestUrl = SOURCE_API + 'source/magento/V1/guest-carts/{cartId}/billing-address/';
var loggedInUrl = SOURCE_API + 'source/magento/V1/carts/mine/billing-address/';
var request = (KANE.isLoggedIn ? loggedInUrl : guestUrl);
return $.ajax({
method: 'POST',
url: request,
data: JSON.stringify({
'address': {
'region_code': 'TX',
'country_id': KANE.territory,
'street': ['1200 Lakeside Pkwy'],
'postcode': $scope.creditCardZip,
'city': 'Flower Mound',
'firstname': 'Suraj',
'lastname': 'Kolluri',
'saveInAddressBook': 0,
'telephone': $scope.phoneNumber,
'email': $('#checkout-email').val(),
}
}),
contentType: "application/json",
dataType: "json"
}).then($scope.sendShippingInformation)
.then($scope.sendPaymentType)
.then(function(response) {
console.log(response);
});
}
// Second Request where I need to handle the error
$scope.sendShippingInformation = function() {
console.log('Send Shipping Information');
var guestUrl = SOURCE_API + 'source/magento/V1/guest-carts/{cartId}/shipping-information/';
var loggedInUrl = SOURCE_API + 'source/magento/V1/carts/mine/shipping-information/';
var request = (KANE.isLoggedIn ? loggedInUrl : guestUrl);
return $.ajax({
method: 'POST',
url: request,
data: JSON.stringify({
'addressInformation': {
'shippingAddress': {
'region_code': $scope.state,
'country_id': KANE.territory,
'street': [$scope.streetAddress1],
'postcode': $scope.zip,
'city': $scope.city,
'firstname': $scope.firstName,
'lastname': $scope.lastName,
'email': $scope.email,
'telephone': $scope.phoneNumber,
},
'shippingMethodCode': templateShippingMethods[$scope.shippingMethod].method_code,
'shippingCarrierCode': templateShippingMethods[$scope.shippingMethod].id
}
}),
contentType: "application/json",
dataType: "json"
})
}
// Determine Payment Type
$scope.sendPaymentType = function() {
if ($('#paypal').is(':checked')) {
console.log("Checking Out With PayPal");
var guestUrl = SOURCE_API + 'source/paypal/checkout/';
var loggedInUrl = SOURCE_API + 'source/paypal/checkout/';
var request = (KANE.isLoggedIn ? loggedInUrl : guestUrl);
var products = [],
total = 0;
$('#my-cart .product').each(function(index, el) {
total += parseFloat($(el).attr('data-total'));
products.push({
'name': $(el).attr('data-title'),
'sku': $(el).attr('data-sku'),
'price': $(el).attr('data-price'),
'quantity': $(el).attr('data-qty')
});
});
return $.ajax({
method: 'POST',
url: request,
data: JSON.stringify({
'items': products,
'shipping_address': {
'line1': $scope.streetAddress1,
'line2': $scope.streetAddress2,
'city': $scope.city,
'country_code': KANE.territory,
'postal_code': $scope.zip,
'state': $scope.state,
'phone': '9999999999',
normalization_status: 'UNKNOWN',
'status': 'CONFIRMED',
'type': 'HOME',
'recipient_name': $scope.firstName,
},
'total': KANE.cartObject.grandTotal,
'currency': 'USD',
'subtotal': KANE.cartObject.subtotal,
'tax': '0.00',
'shipping': parseFloat(templateShippingMethods[$scope.shippingMethod].price).toFixed(2).toString(),
'shipping_discount': KANE.cartObject.discountAmount,
'email': ($scope.email) ? $scope.email : '',
'description': 'This is the payment transaction description.'
}),
contentType: "application/json",
dataType: "json"
}).then(function(response) {
console.log(response.approvalUrl);
window.location.replace(response.approvalUrl);
})
} else {
console.log('Send Stripe Payment');
var guestUrl = SOURCE_API + 'source/magento/V1/guest-carts/{cartId}/order/';
var loggedInUrl = SOURCE_API + 'source/magento/V1/carts/mine/order/';
if (KANE.isLoggedIn) {
return $.ajax({
method: 'PUT',
url: loggedInUrl,
data: JSON.stringify({
"paymentMethod": {
"method": "md_stripe_cards",
"additionalData": {
"md_stripe_card_id": userDataObject.savedPaymentMethods[$scope.paymentMethod].cardId,
"md_stripe_customer_id": userDataObject.stripeCustId,
"from_venue": "1"
}
},
}),
contentType: "application/json",
dataType: "json"
})
} else {
return $.ajax({
method: 'POST',
url: guestUrl,
data: JSON.stringify({
"paymentMethod": {
"method": "md_stripe_cards",
"additionalData": {
"md_stripe_token": "tok_u5dg20Gra",
"from_venue": "1"
}
}
}),
contentType: "application/json",
dataType: "json"
})
}
}
}
You could try something like this:
(pseudo-code)
$scope.b_ok = false
$scope.give_up = false
p = a.then(
while (!$scope.b_ok && !$scope.give_up) {
p = b.then(c)
}
)
p.catch(show_error)
and in b:
return ajax.then(set_b_ok_to_true).catch(tell_them_to_retry)
and in tell_them_to_retry you'll want to reject(reason) so that c does not follow b.

How to return transformed data from a $http.json request in angular?

How can I return the APIData.map and not the default success APIdata using $http.jsonp?
LangDataService Constructor:
languages.LangDataService = function($http, $q) {
this.langDefer = $q.defer();
this.isDataReady = this.langDefer.promise;
};
languages.LangDataService.prototype.getApi = function() {
return this.isDataReady = this.http_.jsonp(URL, {
params: {}
})
.success(function(APIData) {
return APIData.map(function(item){
return item + 1; //just an example.
});
});
};
A Ctrl using LandDataService:
languages.LanguageCtrl = function(langDataService) {
languages.langDataService.isDataReady.then(function(data){
console.log('whooo im a transformed dataset', data);
});
}
Use then instead of success in getApi function.
Try a version of the following:
https://jsfiddle.net/L2ndft4w/
// define the module for our AngularJS application
var app = angular.module('App', []);
app.factory('LangDataService', function($q,$http) {
return {
getApi: function() {
var defer= $q.defer();
$http({
url: 'https://mysafeinfo.com/api/data?list=zodiac&format=json&alias=nm=name',
dataType: 'json',
method: 'GET',
data: '',
headers: {
"Content-Type": "application/json"
}
}).
success(function (data) {
defer.resolve(data.map(function(item){
return item.name;
}));
})
return defer.promise;
}
};
});
// invoke controller and retrieve data from $http service
app.controller('DataController', function ($scope, LangDataService) {
LangDataService.getApi().then(function(data){
$scope.data = JSON.stringify(data, null, 2);
});
});
Returns:
[
"Aquarius",
"Aries",
"Cancer",
"Capricorn",
"Gemini",
"Leo",
"Libra",
"Ophiuchus",
"Pisces",
"Sagittarius",
"Scorpio",
"Taurus",
"Virgo"
]
Although, since $http is already a promise, there's probably a shorter way to do this... ($q.when?)

Categories

Resources