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

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
}
});

Related

Prometheus Pushgateway from Browser JS/AJAX

I am searching for an example on how to push metric to the pushgateway via ajax.
echo 'some_metric 42' | curl --user user:pass --data-binary #- https://example.com/metrics/job/author_monitoring/jobname/count_open
with curl it works perfect!
I don't know how to translate this in js/jquery.
Maybe someone has an example
Here is what I got so far.
(function ($, $document) {
"use strict";
function textToBin(text) {
return (
Array
.from(text)
.reduce((acc, char) => acc.concat(char.charCodeAt().toString(2)), [])
.map(bin => '0'.repeat(8 - bin.length) + bin)
.join(' ')
);
}
var username = "user";
var password = "pass";
var metric = 'some_metric 42';
var binaryData = textToBin(metric);
$.ajax({
url: "https://example.com/metrics/job/author_monitoring/jobname/count_open",
data: binaryData,
type: 'POST',
crossDomain: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
},
success: function () {
console.log("Success");
},
error: function () {
console.log('Failed!');
}
});
})($, $(document));
here is the error:
text format parsing error in line 1: invalid metric name
okay I got it.
There is an easy solution, import is the \n at the end of the string.
(function ($, $document) {
"use strict";
var username = "user";
var password = "pass";
var metric = 'some_metric 42\n';
$.ajax({
url: "https://example.com/metrics/job/author_monitoring/jobname/count_open",
data: metric,
type: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.setRequestHeader("Content-Type", "text/plain");
},
success: function () {
console.log("Success");
},
error: function () {
console.log('Failed!');
}
});
})($, $(document));

Angular display a single record from json

I've just started getting into using Angular and having an issue displaying a single record that is being returned from using $http (get). I'm getting the data back correctly. This is the html I've got....
<div ng-controller="UserDataController as udCtrl">
Name: {{udCtrl.user.name}}
</div>
<div id="debug" style="margin-top:24px;border:solid 1px #900;background:#efefef;min-height:100px"></div>
have also tried and a couple of other variations...
Name: {{udCtrl.name}}
Javascript:
(function() {
var app = angular.module('rtcTimesheet', []);
var servicePath="/angular/";
$("#debug").append("Starting...<br/>");
app.controller("UserDataController",["$http",function($http){
var user=this;
user=[];
$http({
method: 'GET',
url: servicePath+'login.php',
params: {
un: "username",
pwd: "123456789"
}
}).then(function(response){
if(response.data.hasOwnProperty("HasError")) {
$("#debug").append("ERROR: " + response.data.ErrorMessage);
} else {
$("#debug").append("Data: " + JSON.stringify(response.data));
user=response.data;
}
},function (err){
alert("ERROR: "+err.status); //data, status, headers, config, statusText
});
}]);
app.controller("UserTest",function(){
this.user=users;
});
var users = {
id: '1',
name: 'Joe Bloggs'
};
})();
This is what is returned in JSON format and I can see this in the little debug area I created.
{"data":{"id":"1","name":"Joe Bloggs"}
if I change the html to use the code below it works.
<div ng-controller="UserTest as udCtrl">
Name: {{udCtrl.user.name}}
</div>
I just cannot see where I'm going wrong and why it will not display the returned name.
Define the user variable on $scope and access it with $scope.user. You are having referance problem.
Example
//Define user variable like this.
$scope.user = {};
//On response -->
}).then(function(response){
if(response.data.hasOwnProperty("HasError")) {
$("#debug").append("ERROR: " + response.data.ErrorMessage);
} else {
$("#debug").append("Data: " + JSON.stringify(response.data));
$scope.user=response.data;
}
}
EDIT
If you want to use udCtrl referance define variable under thisvariable on controller.
//Define user variable like this.
var ctrl = this;
ctrl.user = {};
//On response -->
}).then(function(response){
if(response.data.hasOwnProperty("HasError")) {
$("#debug").append("ERROR: " + response.data.ErrorMessage);
} else {
$("#debug").append("Data: " + JSON.stringify(response.data));
ctrl.user=response.data;
}
}
EDIT 2 FOR ABSOLUTE ANSWER
(function() {
var app = angular.module('rtcTimesheet', []);
var servicePath="/angular/";
$("#debug").append("Starting...<br/>");
app.controller("UserDataController",["$http",function($http){
var udCtrl=this;
udCtrl.user=[];
$http({
method: 'GET',
url: servicePath+'login.php',
params: {
un: "username",
pwd: "123456789"
}
}).then(function(response){
if(response.data.hasOwnProperty("HasError")) {
$("#debug").append("ERROR: " + response.data.ErrorMessage);
} else {
$("#debug").append("Data: " + JSON.stringify(response.data));
udCtrl.user=response.data;
}
},function (err){
alert("ERROR: "+err.status); //data, status, headers, config, statusText
});
}]);
app.controller("UserTest",function(){
this.user=users;
});
var users = {
id: '1',
name: 'Joe Bloggs'
};
})();

Angular forEach with comparison from json?

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);
});
});
};

Add authorization header with transformRequest

this should be quite easy, but in the end is not working :(.
We use Angular 1.4.3, and we try to add an Authorization header value before some API calls.
Long story short, there is a factory:
angular.module('xxx').factory('factory', function ($resource, addBasicAuth) {
return $resource(baseUrl, {}, {
query: {method: 'GET', isArray: true, transformRequest: addBasicAuth},
...
});
});
And the addBasicAuth goes as follows:
angular.module('xxx').factory('addBasicAuth', function ($rootScope) {
return function (data, headersGetter) {
var user = ($rootScope.user);
headersGetter().Authorization = 'Basic ' + Base64.encode(user.username + ':' + user.password);
return angular.toJson(data);
};
});
And in theory all should work fine, but for the reason I do not understand, the requestHeader is untouched (checked in Developers Tools/Network - Chrome).
What am I doing wrong? Thanks!
my colleague helped me out with a following solution;
instead of transformRequest we use headers and it goes like this:
angular.module('xxx').factory('factory', function ($resource, addBasicAuth) {
return $resource(baseUrl, {}, {
query: {
method: 'GET',
isArray: true,
headers: addBasicAuth()
},
...
});
});
and the addBasicAuth is now a factory function:
angular.module('xxx').factory('addBasicAuth', function ($rootScope) {
return function () {
var user = ($rootScope.user);
return {'Authorization': 'Basic ' + Base64.encode(user.username + ':' + user.password)};
};
});
Works like a charm.

Add Javascript function return value to output

I have the following code:
var Faculty180API = {
token: '1a88be52b9e9dd649998c3c1979b6b5c79cc160e',
base_url: 'https://www.faculty180.com/api.php',
account: 'DemoLinks',
last_results: null,
fetch: function(path, params, callback) {
$.ajax((this.base_url + this.make_path(path)), {
data: this.make_params(params),
crossDomain: true,
xhrFields: { withCredentials: true },
success: callback,
dataType: 'json',
error: function(xhr) {
if(xhr.status == 200) {
$('#results').text(xhr.responseText);
}
else {
$('#URL').text(Faculty180API.base_url . HERE);
$('#results').text(xhr.status + ' - ' + xhr.statusText);
}
}
});
},
make_params: function(params){
params['token'] = this.token;
return $.param(params);
},
}
In the line that I have written HERE, I want to add what Function(params) returns to the output. How can I do this?
Haven't tested this, but I'm thinking you can just call it like this:
$('#URL').text(Faculty180API.base_url + Faculty180API.make_params( yourParams ) );
Also note that I changed your . (after base_url) to a +. Dot is string concatenation in PHP; in Javascript it's +

Categories

Resources