Remove JSON object in Angular - javascript

I have a file (courses.json) that I want to remove courses from when I click on the 'x' next to the course-name. I am very much a beginner at this, and I can't really get it to work.I have no problem reading from the file, but nothing happens when I click the 'x'. Very grateful for all the help I can get!
This is my code:
var app = angular.module('myApp', []);
app.controller('courses', function($scope, $http) {
$http.get("courses.json").success(function(data) {
$scope.courses = data.kurser;
});
});
function courses($scope, courses) {
$scope.deleteItem = function (key) {
delete $scope.courses[key];
}
}
HTML:
<div ng-app="myApp">
<ul ng-controller="courses">
<li ng-repeat="(key, value) in courses" id="course-{{value.courseId}}">
{{value.courseName}} <a ng-click="deleteItem(key)">x</a>
</li>
</ul>
</div>

You should define deleteItem method in the same controller where you load data, otherwise courses function is not linked to the application anyhow:
app.controller('courses', function($scope, $http) {
$http.get("courses.json").success(function(data) {
$scope.courses = data.kurser;
});
$scope.deleteItem = function (key) {
delete $scope.courses[key];
}
});

Related

AngularJS: Trying to get data from variable

cartController in AngularJS:
angular.module('demo', [])
.controller('Hello', function($scope, $http) {
$scope.refreshCart = function() {
$http.get('http://localhost:8080/rest/cart')
.success(function(response) {
$scope.items = response.data;
});
};
$scope.removeFromCart = function(productId) {
$http.delete('/delete/' + productId)
.success(function (data) {
$scope.refreshCart();
});
};
$scope.addToCart = function(productId) {
$http.put('/add/'+ productId)
.then(function(response) {
$scope.refreshCart();
});
};
});
First HTML file (here everything works):
<a href = "#" type="button" class="btn btn-info" th:attr="
ng-click='addToCart(' + ${product.id} + ')'" data-toggle="modal" data-target="#myModal">
Add to cart</a>
Second HTML file:
<html lang="en" xmlns:th="http://www.thymeleaf.org" ng-app="demo">
<script src="http://localhost:8080/cartController.js"></script>
<body ng-controller="Hello">
(...)
<tbody ng-repeat="item in items.cartItemList">
<div class="row">
<h4 class="nomargin">{{item.product.name}}</h4>
<p>{{item.product.description}}</p>
</div>
<td data-th="Price">{{item.price}} PLN</td>
<td data-th="Quantity">{{item.quantity}}</td>
</tbody>
(...)
So what i need to do is:
1) Hit the button in first HTML file, and load JSON to $scope.items (it works).
2) Show the second HTML file, load JSON from $scope.items, and view this JSON to user.
But when I get the second HTML file and try to show data, the $scope.items is empty. Can you help pleae ?
Do you get console errors in your browser? Maybe you have to define items on the controller as empty array like in the example below ...
.controller('Hello', function($scope, $http) {
//define empty array
$scope.items = [];
$scope.refreshCart = function() {
$http.get('http://localhost:8080/rest/cart')
.success(function(response) {
$scope.items = response.data;
});
};
//...
}
I would suggest you to use broadcast and emit. Pass data between the controllers using these. You should use $broadcast if you want to pass data from parent controller to child controller. And emit if the other way around.

Invoke one controller from another

I am a total newbie in AngularJs, so please be patient with me.
I have the following angular App, which contains two controllers
(function () {
angular.module("app-machines", ['ngFlatDatepicker'])
.controller('mainController', ['$scope', mainController])
.controller("machinesController", machinesController);;
function mainController($scope) {
$scope.datepickerConfig_From = {
allowFuture: true,
dateFormat: 'DD.MM.YYYY',
minDate: moment.utc('2015-09-13'),
maxDate: moment.utc('2015-09-17')
};
$scope.datepickerConfig_To = {
allowFuture: true,
dateFormat: 'DD.MM.YYYY',
minDate: moment.utc('2015-09-13'),
maxDate: moment.utc('2015-09-17')
};
$scope.date_from = "14.09.2015";
$scope.date_to = "15.09.2015";
$scope.change = function () {
//somehow execute machinesController get function
};
}
function machinesController($http) {
var vm = this;
vm.errorMessage = "";
vm.machines = [];
$http.get("/api/machine/2015-09-14_2015-09-16")
.then(function (response) {
//success
angular.copy(response.data, vm.machines);
}, function (error) {
//failure
vm.errorMessage = "Failed to load data:" + error;
});
}
})();
my machinesController is supposed to call a GET function with parameters. Here parameters are 2015-09-14 and second one is 2015-09-16 (for now they are hard coded).
What I would like to achieve is, that I have a two input controls on my main page, which trigger $scope.change function (located at the bottom of the first mainController). Here I would like to pass values of date_from and date_to to the GET function, so that I can retrieve certain values.
What I can do (in the end, if nothing works) is to copy the ode from machinesController into my mainController and that would solve the problem.
However I would like to learn how to work with this a bit better, therefore I would like to learn how to do it the proper way (in this case calling one module from the other).
What do I need to change in order to achieve this?
EDIT:
The reason why I have machinesController is, as was mentioned, to donwload the json data and show it to the user. So in the end in my html code I have the following:
<div ng-controller="machinesController as vm" class="col-md-6 col-md-offset-3">
<div class="text-danger" ng-show="vm.errorMessage"> {{ vm.errorMessage }}</div>
<table class="table table-responsive table-striped">
<tr ng-repeat="machine in vm.machines">
<td> {{ machine.name }}</td>
</tr>
</table>
</div>
Which displays a table with machine names.
you can active this is two way:
First : $broadcast and $on
//PUBLISHER
angular.module('myApp').controller('CtrlPublish', ['$rootScope', '$scope',
function ($rootScope, $scope) {
$rootScope.$broadcast('topic', 'message');
}]);
//SUBSCRIBER
angular.module('myApp').controller('ctrlSubscribe', ['$scope',
function ($scope) {
var unbind = $scope.$on('topic', function (event, arg) {
$scope.receiver = 'got your ' + arg;
});
$scope.$on('$destroy', unbind);
}]);
Second : Through common service
angular.module('myApp', [], function($provide) {
$provide.factory('msgBus', ['$rootScope', function($rootScope) {
var msgBus = {};
msgBus.emitMsg = function(msg) {
$rootScope.$emit(msg);
};
msgBus.onMsg = function(msg, scope, func) {
var unbind = $rootScope.$on(msg, func);
scope.$on('$destroy', unbind);
};
return msgBus;
}]);
});
and use it in controller like this:
controller 1
function($scope, msgBus) {
$scope.sendmsg = function() {
msgBus.emitMsg('somemsg')
}
}
controller 2
function($scope, msgBus) {
msgBus.onMsg('somemsg', $scope, function() {
// your logic
});
}
From : Post
To takes care of downloading the data you should use a factory.
Look at this answer for further details about good practices.
I modified your code to use a factory.
angular.module("app-machines", ['ngFlatDatepicker'])
.factory('MachinesService', ['$http', MachinesService])
.controller('mainController', ['$scope', 'MachinesService', mainController]);
function mainController($scope, MachinesService) {
// date pickers config...
$scope.date_from = "14.09.2015";
$scope.date_to = "15.09.2015";
$scope.change = function () {
MachinesService.getMachines($scope.date_from, $scope.date_to).then(function (response) {
vm.machines = response.data;
}, function (error) {
vm.errorMessage = "Failed to load data:" + error;
});
};
}
function MachinesService($http) {
return {
getMachines: getMachines
};
function getMachines(from, to) {
return $http.get("/api/machine/" + from + "_" + to);
}
}
Why dont u create a service instead of second controller and inject it into your main controller and use it.
May be you can refer this :
http://ilikekillnerds.com/2014/11/angularjs-call-controller-another-controller/

How to show HTML with AngularJS from JSON string

I am struggling to display HTML code from JSON string. You can see HTML tags in address. Is there any way I can properly display it?
My template is:
<div ng-app ng-controller="jsonp_example">
<ul ng-repeat="item in data">
<li>{{item.ID}}</li>
<li>{{item.post_title}}</li>
<li ng-bind-html-unsafe="getContent(obj)">{{item.custom_fields.sponsor_address}}</li>
<li>
<img src="{{item.custom_fields.sponsor_logo}}" width="100">
<ul>
<li>
<hr>
</li>
</ul>
</li>
</ul>
</div>
And script:
function jsonp_example($scope, $http) {
$scope.getContent = function (obj) {
return obj.custom_fields.sponsor_address
};
var url = "https://eventident.com/api/getposts/?auth_key=s2mEus39R296M5F6n343A3dh9c62f7cm&custom_post=sponsors&callback=JSON_CALLBACK";
$http.jsonp(url).success(function (data) {
$scope.data = data.result;
});
}
Please feel free to amend my jsfiddle: http://jsfiddle.net/1295z4bc/
Did you include angular-sanitize.js as a dependency ? (as a script and as angular module dependency)
Also, you don't need to {{}} with ng-bind-html, just
<li ng-bind-html="item.custom_fields.sponsor_address"></li>
will do.
You need to include the ngSanitize service and directly use ng-bind-html.
Here is an updated jsfiddle from yours: http://jsfiddle.net/e01xj547/9/
You might need to explicitly trust the html string by using the $sce service. E.g var trustedHtml=$sce.trustAsHtml('<em>My html string</em>');
In your case to following usage would be appropirate:
function jsonp_example($scope, $http, $sce) {
$scope.getContent = function (obj) {
return $sce.trustAsHtml(obj.custom_fields.sponsor_address);
};
var url = "https://eventident.com/api/getposts/?auth_key=s2mEus39R296M5F6n343A3dh9c62f7cm&custom_post=sponsors&callback=JSON_CALLBACK";
$http.jsonp(url).success(function (data) {
$scope.data = data.result;
});
}
Example usage: http://jsbin.com/zopenoqipi/2/edit?html,js,output

Update a service value from a parent controller

I've been searching for hours how to update a service value from a nested controller.
My child controller needs to update a value in a service. And that value needs to be shown in the parent controller.
I've made a jsfiddle to make it more clear and easy to help
http://jsfiddle.net/jtsmduxw/3/
<body ng-app="MyApp">
<div ng-controller="parentCtrl">
<p>{{username}}</p>
<div ng-controller="childCtrl">
<p>{{username}}</p>
</div>
</div>
</body>
-
var app = angular.module("MyApp", []);
app.service('authenticationSrv', function () {
var user = 'anonymous';
return {
getUser: function () {
return user;
},
setUser: function (value) {
user = value;
}
};
});
app.controller("parentCtrl", function ($scope, authenticationSrv) {
$scope.username = authenticationSrv.getUser();
});
app.controller("childCtrl", function ($scope, authenticationSrv) {
authenticationSrv.setUser('my name'); // I need this function to also update the scope of the parent
$scope.username = authenticationSrv.getUser();
});
(I've read and tried Update parent scope variable, but I could not make it work with the service.)
Thanks!
Make use of an object literal instead of the variable username.
Parent
app.controller("parentCtrl", function ($scope, authenticationSrv) {
$scope.parentObject = {};
$scope.parentObject.username = authenticationSrv.getUser();
});
Child
app.controller("childCtrl", function ($scope, authenticationSrv) {
authenticationSrv.setUser('my name');
$scope.parentObject.username = authenticationSrv.getUser();
});
Working Example
var app = angular.module("MyApp", []);
app.service('authenticationSrv', function () {
var user = 'anonymous';
return {
getUser: function () {
return user;
},
setUser: function (value) {
user = value;
}
};
});
app.controller("parentCtrl", function ($scope, authenticationSrv) {
$scope.parentObject = {};
$scope.parentObject.username = authenticationSrv.getUser();
});
app.controller("childCtrl", function ($scope, authenticationSrv) {
authenticationSrv.setUser('my name');
$scope.parentObject.username = authenticationSrv.getUser();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="MyApp">
<div ng-controller="parentCtrl">
<p>{{parentObject.username}}</p>
<div ng-controller="childCtrl">
<p>{{parentObject.username}}</p>
</div>
</div>
</body>
Make user in the Service an object instead of a primitive (string). Then use {{user.name}} in your view.
Notice that I did some minor changes to authenticationSrv.setUser()
and renamed it to authenticationSrv.setUserName().
See my working fiddle: https://jsfiddle.net/rbwk3rqb/
var app = angular.module("MyApp", []);
angular.module("MyApp")
.service('authenticationSrv', function () {
var user = {name: 'anonymous'};
return {
getUser: function () {
return user;
},
setUserName: function (value) {
user.name = value;
}
};
});
angular.module("MyApp")
.controller("parentCtrl", function ($scope, authenticationSrv) {
$scope.user = authenticationSrv.getUser();
});
angular.module("MyApp")
.controller("childCtrl", function ($scope, authenticationSrv) {
authenticationSrv.setUserName('my name');
$scope.user = authenticationSrv.getUser();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="MyApp">
<div ng-controller="parentCtrl">
<p>{{user.name}}</p>
<div ng-controller="childCtrl">
<p>{{user.name}}</p>
</div>
</div>
</body>
As user is a primitive value in the service, when you put the value from the service to your controller's scope with this line:
$scope.username = authenticationSrv.getUser();
the value of user is copied into $scope.username. So just because later on you overwrite the value of user in the service, nothing is changing in your "parent" $scope.
There are several ways to get around this, the easiest is probably to create a user object in your service - if you store the reference to this object in your scopes, it will reflect the changes made to it from other controllers. (Objects in javascript are passed by reference value, so all controllers will be affecting the same object, not copies of the values.) For the actual implementation, I'd guide you back to the same link you posted - when you tried implementing that, what was the problem with it? Show us the code you tried.
Alternatively, you can also implement the observer pattern using this service (this is considerably more work), or use events on the scope hierarchy to notify the controllers of the change of user (this is a questionable practice).
The idea is to create and object to update and not just a primitive:
$scope.user = {};
$scope.user.name = authenticateSrv.getUser();
and in the child scope you just set it:
$scope.user.name = authenticateSrv.setUser('my name');
here is a Fiddle

Passing data from Angular service to controller and refreshing view

So I have a bootstrap list:
<div class="ajax_company_list" ng-app="app">
<div class='list-group' ng-controller="PolicyController as policyCtrl">
<a href="#" class='list-group-item' ng-repeat="company in policyCtrl.companies">{{company.primary_name}}
</a>
<div id="loadingIcon" class='list-group-item'>
Loading...
</div>
</div>
</div>
Here is my Angular Javascript:
var app = angular.module('app', []);
app.controller('PolicyController', ['$scope', 'CompanyService', function($scope, CompanyService) {
$scope.companies = [
{
policy_number: 12345,
primary_name: "test"
}
];
$scope.getCompanies = function() {
CompanyService.fetchCompanies()
.success(function(data) {
$scope.companies = data.companies;
})
}
}]);
app.factory('CompanyService', ['$http', function($http) {
return {
fetchCompanies: function() {
return $http.get('http://spoonerinc:8886//json/glmod_Spooner-Inc?pagenum=1');
}
}
}]);
I basically have 2 questions. If I set $scope.companies equal to an array of objects, it does not show up but if I change $scope.companies to this.companies, it starts working again. Why is this?
2nd question, I can see the service call running in my net tab and can console.log the data and it reads fine. But it is not updating my actual list at all and I'm not sure what I'm doing wrong.
I am fairly new to Angular so if there is any advice on how I can do my code better, please let me know.
Thanks!
Because you are using the "Controller As" syntax, which effectively publishes the entire controller object to the scope.
What happens under the hood looks something like this:
function myCtrl($scope){
$scope['someAlias'] = this;
}
If you are going to use the controller as syntax, it's best to use a more object based approach instead of pushing things onto the $scope
Either on the prototype:
function myCtrl(companiesService){
this.companiesService = companiesService;
this.init();
}
myCtrl.prototype = {
init:function(){
var _this = this;
_this.companiesService.get()
.then(function(result){
_this.companies = result.data;
});
}
};
Or as closure style object:
function myCtrl(comapniesService){
var ctrl = {};
function init(){
companiesService.get()
.then(function(result){
ctrl.companies = result.data;
});
}
return ctrl;
}
For your second question, I think your problem is here:
ng-repeat="company in policyCtrl.companies"
You don't need to specify the controller as a prefix, since you've already declared it with ng-controller. It should be:
ng-repeat="company in companies"
And ng-controller to be:
ng-controller="PolicyController"
My guess is that the first problem will go away once you correct this.

Categories

Resources