AngularJS syntax error / expected expression? - javascript

I'm trying to add a post method to my controller, but I keep getting a syntactical error that I can't trace. My goal is for a single controller to fetch() on init, and then have buttons within the controller that can call additem(itemid) on click.
Here's my app.js:
(function(angular) {
'use strict';
angular.module('myApp', [])
.controller('ItemsController', ['$scope', '$http', '$log',
function($scope, $http) {
$scope.method = 'GET';
$scope.url = '/path/to/api';
$scope.fetch = function() {
$scope.code = null;
$scope.response = null;
var response = $http({method: $scope.method, url: $scope.url}).
then(function(response) {
$scope.status = response.status;
$scope.data = response.data;
$scope.thedata = JSON.stringify(response.data);
$scope.count = $scope.data.length
console.log($scope.thedata);
console.log($scope.data[0]);
}, function(response) {
$scope.data = response.data || "Request Failed";
$scope.status = response.status;
})
};
$scope.additem = function(itemid) {
var itemdata = new Object();
itemdata.itemid = itemid;
$http.post($scope.url, itemdata).success(function(data){
//Callback function here.
//"data" is the response from the server.
if (data.status === "success") {
console.log("Added!")
}
});
}
}]),
]); // SyntaxError: expected expression, got ']'
})(window.angular);
On the line just before (window.angular); I get this error in the Firefox console:
SyntaxError: expected expression, got ']'
I'm pretty sure my indentation is a little messed up towards the end, so it's tough to discern what is causing it...

Ending the script like this corrected the syntax:
};
}
]);
});
(window.angular);

Related

Get data before page load in angularJS

I am trying to fetch a drop downlist before the page load using angular $http. I tried few combinations but it keep on giving the same error:
Error: [$injector:unpr] Unknown provider: officeListProvider <- officeList <- myController
http://errors.angularjs.org/1.4.3/$injector/unpr?p0=officeListProvider%20%3C-%20officeList%20%3C-%20myController
I am few weeks old in angular so please pardon in case of any silly mistakes.
var myApp = angular.module('myApp',['ngRoute']);
myApp.config(['$routeProvider',function ($routeProvider) {
$routeProvider.when('../../home/goEeUpdateAngular.obj', {
templateUrl: '/employee_update_angular.jsp',
controller: 'myController',
resolve: {
officeList: function(officeListFactory) {
return officeListFactory.getOfficeList();
}
}
});
}]);
myApp.factory('officeListFactory', function($http, $window) {
$window.alert("Hi");
var factoryResult = {
getOfficeList: function() {
var promise = $http({
method: 'GET',
url: '../../home/goOfficesList.obj'
}).success(function(data, status, headers, config) {
console.log (data);
return data;
});
return promise;
}
};
console.log (factoryResult.getOfficeList());
return factoryResult;
});
myApp.controller('myController',function ($scope,officeList) {
$scope.officeListFactory = officeListFactory.data;
});
The error says "officeListProvider" is not present or not visible, you need to add it as dependency.
Please try the below change:
var ctrl = angular.module('myApp.controllers', []);
to
var ctrl = angular.module('myApp.controllers', ['myApp.services']);
and also please use the same service name it is either srvOfficeList or officeList, and also check your service factory, it is not right - example:AngularJS : factory $http service
Hope it will fix the issue.
Please try to create a CodePen (or similar tool) while posting the question, so that the Answer can tried/fixed in there and shared back with you.
In controller you should call only officeList. Here is the working JSFIDDLE. I too sample webapi instead of your url
var myApp = angular.module('myApp',['ngRoute']);
myApp.config(['$routeProvider',function ($routeProvider) {
$routeProvider.when('../../home/goEeUpdateAngular.obj', {
templateUrl: '/employee_update_angular.jsp',
controller: 'myController',
resolve: {
officeList: function(officeListFactory) {
return officeListFactory.getOfficeList();
}
}
});
}]);
myApp.factory('officeListFactory', function($http, $window) {
$window.alert("Hi");
var factoryResult = {
getOfficeList: function() {
var promise = $http({
method: 'GET',
url: '../../home/goOfficesList.obj'
}).success(function(data, status, headers, config) {
console.log (data);
return data;
});
return promise;
}
};
console.log (factoryResult.getOfficeList());
return factoryResult;
});
myApp.controller('myController',function ($scope,officeList) {
$scope.officeListFactory = officeList.data; //changes are made here
});

TypeError: Main.login is not a function

I am trying to implement this example to my project. you can see the front-end side code here.
this is my controller
(function(){
'use strict';
/* authentication Controllers */
var app = angular.module('pook');
app.controller('authCtrl',['$http','$rootScope', '$scope', '$location', '$localStorage', 'ngToast', 'Main', function($http, $scope, $location, $localStorage, ngToast, Main){
$scope.login = function(){
var formData = {
username: $scope.username,
password: $scope.password
};
Main.login(formData, function(res) {
if (res.type == false) {
alert(res.data)
} else {
$localStorage.token = res.data.token;
window.location = "/";
}
}, function() {
$rootScope.error = 'Failed to signin';
});
}
}]);
})();
below is my factory service
(function(){
'use strict';
var app = angular.module('pook')
app.factory('Main', ['$http', '$localStorage', function($http, $localStorage){
var baseUrl = "127.0.0.1:3000/api";
function changeUser(user) {
angular.extend(currentUser, user);
}
function urlBase64Decode(str) {
var output = str.replace('-', '+').replace('_', '/');
switch (output.length % 4) {
case 0:
break;
case 2:
output += '==';
break;
case 3:
output += '=';
break;
default:
throw 'Illegal base64url string!';
}
return window.atob(output);
}
function getUserFromToken() {
var token = $localStorage.token;
var user = {};
if (typeof token !== 'undefined') {
var encoded = token.split('.')[1];
user = JSON.parse(urlBase64Decode(encoded));
}
return user;
}
var currentUser = getUserFromToken();
return {
save: function(data, success, error) {
$http.post(baseUrl + '/users', data).success(success).error(error)
},
login: function(data, success, error) {
$http.post(baseUrl + '/login', data).success(success).error(error)
},
me: function(success, error) {
$http.get(baseUrl + '/me').success(success).error(error)
},
logout: function(success) {
changeUser({});
delete $localStorage.token;
success();
}
};
}
]);
})();
as you can see I copied and pasted from the example word by word and just changed the app name and controller name.
but I get this error below:
TypeError: Main.login is not a function
at Scope.$scope.login (http://127.0.0.1:3000/js/controllers/auth.js:15:12)
at $parseFunctionCall (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:12404:18)
at ngEventDirectives.(anonymous function).compile.element.on.callback (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:21566:17)
at Scope.$get.Scope.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:14466:28)
at Scope.$get.Scope.$apply (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:14565:23)
at HTMLFormElement.<anonymous> (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:21571:23)
at HTMLFormElement.jQuery.event.dispatch (https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.js:4435:9)
at HTMLFormElement.jQuery.event.add.elemData.handle (https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.js:4121:28)
I mean, There IS Main.login function. I don't see why it cant find it.
That is because Main is not what you think it is. When you use explicit dependency injection annotation you need to make sure order and number of dependecies and injected arguments are same.
.controller('authCtrl',
['$http','$rootScope', '$scope', '$location', '$localStorage', 'ngToast', 'Main',
^^^____
function($http, $scope, $location, $localStorage, ngToast, Main)
if you see you have an extra rootScope dependency injected to variable scope, so all the remaining arguments gets shifted. So Main variable actually holds $location object. When in doubt you can always reverify your argument list and do console logging. Proper indentation also helps in cases you have lots of arguments injected.
Remove $rootScope form the injection list and you should be fine.

Angular Factory Not passing data back

I am trying to create an Angular Factory, this is based on a example from a plural site course http://www.pluralsight.com/training/player?author=shawn-wildermuth&name=site-building-m7&mode=live&clip=3&course=site-building-bootstrap-angularjs-ef-azure.
From debugging the code in Chrome it appears to run fine. I can see when I debug it that the service gets my data and puts it in my array but when I look at the controller in either $scope.data or dataService.data the arrays are empty. I don't see any javascript errors. I'm not sure what I'm doing wrong, any suggestions. I'm using AngularJS v1.3.15.
module.factory("dataService", function($http,$routeParams,$q) {
var _data = [];
var _getData = function () {
var deferred = $q.defer();
$http.get("/api/v1/myAPI?mainType=" + $routeParams.mainType + "&subType=" + $routeParams.subType)
.then(function (result) {
angular.copy(result.data,_data);
deferred.resolve();
},
function () {
//Error
deferred.reject();
});
return deferred.promise;
};
return {
data: _data,
getData: _getData
};});
module.controller('dataController', ['$scope', '$http', '$routeParams', 'dataService',function ($scope, $http, $routeParams, dataService) {
$scope.data = dataService;
$scope.dataReturned = true;
$scope.isBusy = true;
dataService.getData().then(function () {
if (dataService.data == 0)
$scope.dataReturned = false;
},
function () {
//Error
alert("could not load data");
})
.then(function () {
$scope.isBusy = false;
})}]);
On
return {
data: _data,
getData: _getData
};});
you have "data: _data," while your array is named just "data". Change the name of the variable to match and it will work:
var _data = [];
Why would you use deferred from $q this way?
The proper way to use $q:
$http.get("/api/v1/myAPI?mainType=" + $routeParams.mainType + "&subType=" + $routeParams.subType)
.success(function (result) {
deferred.resolve(result);
}).error(
function () {
//Error
deferred.reject();
});
And then in controller
dataService
.getData()
.then(function success(result) {
$scope.data = result; //assing retrived data to scope variable
},
function error() {
//Error
alert("could not load data");
});
In fact, there are some errors in your codes :
In your Service, you define var data = [];, but you return data: _data,. So you should correct the defination to var _data = []
you don't define _bling, but you use angular.copy(result.data,_bling);
One more question, why do you assigne the service to $scope.data : $scope.data = dataService ?
EDIT :
Notice that there 3 changes in the following codes:
comment the $scope.data = dataService;, because it makes no sense, and I think that $scope.data should be the data that the service returns.
$scope.data = dataService.data;, as I described in 1st point. You can see the result from the console.
In the if condition, I think that you want to compare the length of the returned data array, but not the data.
module.controller('dataController', ['$scope', '$http', '$routeParams', 'dataService',function ($scope, $http, $routeParams, dataService) {
// $scope.data = dataService;
$scope.dataReturned = true;
$scope.isBusy = true;
dataService.getData().then(function () {
if (dataService.data.length === 0){
$scope.dataReturned = false;
}else{
$scope.data = dataService.data;
console.log($scope.data);
}
},
// other codes...
})}]);

AngularJS: Getting back data with specific id

I'm trying to get a specific product by its id from a JSON file with products. I have some kind of problem as this question
AngularJS : get back data from a json array with an id
the code is similar. I read through that question and the accepted answer there, still can't figured this out. From what I understand the $scope.search() returns a promise which after success triggers the .then() to set get the correct person.
This line of code prints out the products array and also getting the product id from the url.
However it prints out twice in the console.
console.log($scope.products + $routeParams.productId);
app.js
var app = angular.module('gtbApp', [
'ngRoute',
'productControllers'
]);
// Setting up the routes with right controllers and partials
app.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/main', {
templateUrl: 'partials/product-grid.html',
controller: 'ProductController'
})
.when('/product/:productId', {
templateUrl: 'partials/product-detail.html',
controller: 'ProductDetailCtrl'
})
.otherwise({
redirectTo: '/main'
});
}]);
controllers.js
var app = angular.module('productControllers', []);
// For product-grid.html
app.controller('ProductController', ['$http', function($http){
var store = this;
store.products = [];
$http.get('products.json').success(function(data){
store.products = data;
});
}]);
// For product-detail.html
app.controller('ProductDetailCtrl', ['$scope', '$routeParams', '$http', function($scope, $routeParams, $http){
$scope.search = function() {
var url = 'products.json';
// Return a promise object
return $http.get(url).success(httpSuccess).error(function(){
console.log('Unable to retrieve info form JSON file.');
});
}
httpSuccess = function(response) {
$scope.products = response;
}
function getById(arr, id) {
for (var i = 0, len = arr.length; i < len; i++) {
if (arr[i].id === id) {
return arr[i];
}
}
}
$scope.search().then(function(){
// Prints out the products array and id twice
console.log($scope.products + $routeParams.productId);
$scope.product = getById($scope.products, $routeParams.productId);
// Prints out twice "undefined"
console.log($scope.product);
});
}]);
The main question is how to get specific product based on id why in "ProductDetailCtrl"
$scope.product = getById($scope.products, $routeParams.productId);
doesn't work.
Thanks in advance!
Update:
Found out why $scope.product is undefined, it is just because the $routeParams.productId is a string, and in getById() need a integer in second args.
However I don't know why console.log($scope.product); prints out twice.
I don't really understand what your main question is here. But anyways. When you use the $http service it will return a promise, which you eventually will have to unwrap. What you are doing in your code is that you are unwrapping it twice. Which is fine.
With $http response you can either use 'success'/'error' or just 'then' which can take a success and an error callback. Which means you could either unwrap in the search function or after you call the search function.
$scope.search = function() {
var url = 'products.json';
$http.get(url)
.success(function(data){
$scope.product = getById($scope.products, $routeParams.productId);
})
.error(function() {
console.log('Unable to retrieve info form JSON file.');
});
}
You could also do something like:
$scope.search = function() {
var url = 'products.json';
return $http.get(url);
}
$scope.search().then(function(data) {
$scope.product = getById(data, $routeParams.productId);
}, errorCallback);
And the below would achieve the same result
$scope.search = function() {
var url = 'products.json';
return $http.get(url);
}
$scope.search()
.success(function(data) {
$scope.product = getById(data, $routeParams.productId);
})
.error(errorCallback);
or reference the promise:
$scope.search = function() {
var url = 'products.json';
return $http.get(url);
}
var dataPromise = $scope.search();
dataPromise.then(function(data) {
$scope.product = getById(data, $routeParams.productId);
}, errorCallback);
What you need to know is that as long as you're returning something within a success/error/then function it will return a promise which you will have to unwrap in order to get the data.
You should be either using the .success() and .error() on the $http-promise or only then .then()
Do it like this:
app.controller('ProductController', ['$scope', '$routeParams', '$http', function($scope, $routeParams, $http){
$scope.search = function() {
var url = 'products.json';
// Return a promise object
return $http.get(url);
}
.....
$scope.search()
.success(function(data){ // --> data is the products.json
... // handle the successfull call
} );
.error(function(...) {
... // handle the error
} );
// or:
$scope.search().then(
function(data){ // --> data is the products.json
... // handle the successfull call
},
function(...) {
... // handle the error
});
}]);

Angularjs: use ".then" and get response

I want send a http request and get response of this request. I want if data is save, I get database information and if doesn't save, I get errors. For this, I want use .then in angularjs. I create angularjs controller and services to do this. I have below code in angularjs part:
bolouk.js:
'use strict';
var app = angular.module('app');
app.controller('BoloukCtrl', ['$scope', 'Bolouks', function($scope, Bolouks){
$scope.save = function(){
Bolouks.create($scope.bolouk).then(function(data){
$scope.saveBolouk = data;
},function(err){
$scope.err = err;
}
);
};
}]);
boloukService.js:
'use strict';
var app = angular.module('boloukService', ['ngResource']);
app.factory('Bolouks', function($resource) {
return $resource('/api/bolouks.json', {}, {
create: { method: 'POST', isArray: false }
});
});
and I have below code in rails server:
bolouks_controller.rb:
def create
#bolouk = Bolouk.create(bolouk_params)
if #bolouk.valid?
##bolouk.save
respond_with #bolouk, :location => api_bolouks_path
else
respond_with #bolouk.errors, :location => api_bolouks_path
end
end
private
def bolouk_params
params.require(:bolouk).permit(:boloukcode, :north, :south, :east, :west)
end
Request send to rails server correctly and data is save to database right, but I cannot get response of request and when I run function`, I get below error in chrome console:
TypeError: undefined is not a function
at Scope.$scope.save (http://localhost:3000/assets/controllers/bolouk.js?body=1:19:39)
at http://localhost:3000/assets/angular.js?body=1:10973:21
at http://localhost:3000/assets/angular.js?body=1:20088:17
at Scope.$eval (http://localhost:3000/assets/angular.js?body=1:12752:28)
at Scope.$apply (http://localhost:3000/assets/angular.js?body=1:12850:23)
at HTMLFormElement.<anonymous> (http://localhost:3000/assets/angular.js?body=1:20087:21)
at HTMLFormElement.jQuery.event.dispatch (http://localhost:3000/assets/templates/jquery-1.10.2.js?body=1:4627:9)
at HTMLFormElement.elemData.handle (http://localhost:3000/assets/templates/jquery-1.10.2.js?body=1:4295:46)
I think I don't use .then correctly in angularjs controller, I check $q method too, but again get this error. Any one have idea to solve this problem?
you have assign both module in same variable. this may conflict your code. so use this code:
bolouk.js:
'use strict';
var app = angular.module('app',['ngResource']);
app.controller('BoloukCtrl', ['$scope', 'Bolouks', function($scope, Bolouks){
$scope.save = function(){
Bolouks.create($scope.bolouk).$promise.then(function(data){
$scope.saveBolouk = data;
})
.catch(function (err) {
console.log(err);
})
};
}]);
boloukService.js:
'use strict';
app.factory('Bolouks', function($resource) {
return $resource('/api/bolouks.json', {}, {
create: { method: 'POST', isArray: false }
});
});
var app = angular.module('app',['boloukService']);
app.controller('BoloukCtrl', ['$scope', 'Bolouks', function($scope, Bolouks){
$scope.save = function(){
var user = Bolouks.get();
user.get(function(resp) {
//request successful
}, function(err) {
//request error
});
};
}]);
angular.module('boloukService', ['ngResource']);
app.factory('Bolouks', function($resource) {
var savedData = {}
function get() {
return $resource('/api/bolouks.json', {}, {
create: { method: 'POST', isArray: false}
});
}
return {
get: get
}
});
try this one :)

Categories

Resources