I'm tryin to make this example to use xml as json data. But i ve some problem about these code.
courses = x2js.xml_str2json(data);
console.log(courses.books.course);
$scope.todos =courses.books.course;
In the xml of example. There are books and course tag. But i didnt understand where is 'courses' come from.
I'm tryin to do same example with this xml example
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<DocumentElement xmlns="">
<semt_kodlari diffgr:id="semt_kodlari1" msdata:rowOrder="0">
<semt_adi>ALTIKAT</semt_adi>
</semt_kodlari>
</DocumentElement>
</diffgr:diffgram>
And here is my HTML part:
X = x2js.xml_str2json(data);
console.log(X.DocumentElement.semt_kodlari);
$scope.todos = X.DocumentElement.semt_kodlari;
When i run this code i take the "Cannot read property 'semt_kodlari' of undefined" error. So can somebody tell me what is wrong in my code and What is the diffrence about course and course's' ?
I think you are only missing one parent of your object. If you add diffgram to you console.log it should work as expected.
See the demo below or here at jsfiddle.
var todoApp = angular.module('todosApp', []);
todoApp.factory('todoFactory', function ($http) {
var factory = {};
factory.getTodos = function () {
return $http.get("http://cdn.rawgit.com/motyar/bcf1d2b36e8777fd77d6/raw/bfa8bc0d2d7990fdb910927815a40b572c0c1078/out.xml");
}
return factory;
});
todoApp.factory('getXMLDataFactory', function() {
var x2js = new X2JS(),
//xml ="<MyRoot><test>Success</test><test2><item>val1</item><item>val2</item></test2></MyRoot>";
xml = '<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">'+
'<DocumentElement xmlns="">'+
'<semt_kodlari diffgr:id="semt_kodlari1" msdata:rowOrder="0">'+
'<semt_adi>ALTIKAT</semt_adi>'+
'</semt_kodlari>'+
'</DocumentElement>'+
'</diffgr:diffgram>';
console.log(xml, x2js);
return {
get: function() {
return x2js.xml_str2json(xml);
}
};
});
todoApp.controller('todosCtrl', function ($scope, todoFactory, getXMLDataFactory) {
$scope.todos = [];
//loadTodos();
loadData();
function loadTodos() {
todoFactory.getTodos().success(function (data) {
console.log(data);
courses = x2js.xml_str2json(data);
console.log(courses.books.course);
$scope.todos = courses.books.course;
});
}
function loadData() {
console.log('test');
$scope.todos = getXMLDataFactory.get()
.diffgram.DocumentElement.semt_kodlari;
console.log($scope.todos);
}
});
<script src="http://demos.amitavroy.com/learningci/assets/js/xml2json.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="todosApp" ng-controller="todosCtrl">
<h2>Parsing XML data with AngularJS</h2>
{{todos|json}}
</div>
Related
I need to reflect some changes to controller B (inside some event) when I make change at controller A. For that I am using a service.
When I am changing service value from FirstCtrl, ng-change is not firing at SecondCtrl. Is there anything I have missed or need to change?
Please note that I am using angular 1.5.6. and don't want to use watch or even scope.
Below is my code.
var myApp = angular.module('myApp', []);
myApp.factory('Data', function() {
return {
FirstName: ''
};
});
myApp.controller('FirstCtrl', ['Data',
function(Data) {
var self = this;
debugger
self.changeM = function() {
debugger
Data.FirstName = self.FirstName;
};
}
]);
myApp.controller('SecondCtrl', ['Data',
function(Data) {
var self = this;
self.FirstName = Data;
self.changeM = function() {
alert(1);
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="FirstCtrl as c">
<input type="text" ng-model="c.FirstName" data-ng-change="c.changeM()">
<br>Input is : <strong>{{c.FirstName}}</strong>
<div ng-controller="SecondCtrl as c1">
Input should also be here: {{c1.FirstName}}
<input type="text" ng-model="c1.FirstName" data-ng-change="c1.changeM()">
</div>
</div>
<hr>
</div>
As you dont want to use $scope trying modifying the code in order to use $emit and $on feature in angular js to communicate between two controllers. You can refer this link.
var myApp = angular.module('myApp', []);
myApp.factory('Data', function() {
return {
FirstName: ''
};
});
myApp.controller('FirstCtrl', ['Data',
function(Data) {
var self = this;
debugger
self.changeM = function() {
debugger
//Data.FirstName = self.FirstName;
Data.$on('emitData',function(event,args){
Data.FirstName=args.message
document.write(Data.FirstName)
})
};
}
]);
myApp.controller('SecondCtrl', ['Data',
function(Data) {
var self = this;
self.FirstName = Data;
self.changeM = function() {
Data.$emit('emitData',{
message:Data.FirstName
})
};
}
]);
The only way then is to directly copy the reference of the data object within the controller. Note that you don't need ng-change to update the value then.
If you want something else, either wrap the FirstName in a sub object of Data and do the same i did :
Data = {foo:'FirstName'};
Or use $watch since it's the whole purpose of that function.
Here is a working code with copying the Data object in the controller.
var myApp = angular.module('myApp', []);
myApp.factory('Data', function() {
return {
FirstName: ''
};
});
myApp.controller('FirstCtrl', ['Data',
function(Data) {
var self = this;
self.Data=Data;
debugger
self.changeM = function() {
debugger
};
}
]);
myApp.controller('SecondCtrl', ['Data',
function(Data) {
var self = this;
self.Data = Data;
self.changeM = function() {
alert(1);
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="FirstCtrl as c">
<input type="text" ng-model="c.Data.FirstName" data-ng-change="c.changeM()">
<br>Input is : <strong>{{c.Data.FirstName}}</strong>
<div ng-controller="SecondCtrl as c1">
Input should also be here: {{c1.Data.FirstName}}
<input type="text" ng-model="c1.Data.FirstName" data-ng-change="c1.changeM()">
</div>
</div>
<hr>
</div>
The only way I know to solve the problem is using watch, unfortunately. (I am new to angular.)
From the ngChange document (https://docs.angularjs.org/api/ng/directive/ngChange):
The ngChange expression is only evaluated when a change in the input value causes a new value to be committed to the model.
It will not be evaluated:
if the value returned from the $parsers transformation pipeline has not changed
if the input has continued to be invalid since the model will stay null
**if the model is changed programmatically and not by a change to the input value**
I would like to create a service and a controller in AngualrJS. The problem is I need to access to $scope in my service.
I think the good solution is to put this service in the controller directly but I have no idea how to do it.
This is my HTML :
<div ng-controller="myController">
<input type="text" id="idInput" name="idInput" ng-model="nameModel">
<button class="btn btn-default" ng-click="functionWhenClick()">Execute</button>
</div>
This is my controller :
var variableModuleName = angular.module("nameModule",[]);
variableModuleName.controller('controllerName',function($rootScope,$scope, CommonService) {
$scope.nameModel = '';
$scope.scopeFunctionName = function () {
CommonService.myFunction($scope.nameModel);
};
});
This is my service :
variableModuleName.service('CommonService', ['dataService', function(dataService) {
this.loadData = function(param) {
dataService.getCommitData(param).then(function(res) {
if (res.error) {
$scope.chartData = res.chartData;
}
});
};
this.myFunction = function(concatURL){
this.loadData('URL' + concatURL);
}
}]);
I hope you will can help me.
Thanks.
First of all, You can't/shouldn't use $scope in a service. You can't inject $scope in the service. You can pass $scope as a function's parameter but that's a bad idea. Because, we don't want our service to play with all our $scope variables.
Now, to rewrite your service to return chartData from an async operation using dataService (assuming dataService.getCommitData(param) does have a call to server) , you need to handle the promise well.
var d3DemoApp = angular.module("D3demoApp",[]);
// service. Assuming dataService exists
d3DemoApp.service('CommonService', ['dataService', function(dataService) {
this.loadData = function(param) {
return dataService.getCommitData(param).then(function(res) {
// Should the if condition be res.error or !res.error
if (res.error) {
return res;
}
});
};
this.myFunction = function(parameterItem){
return this.loadData('http://localhost:3412/bubble/' + parameterItem);
console.log("Fonction appellée");
}
}]);
// controller
d3DemoApp.controller('controllerFilterSearch',function($rootScope,$scope, CommonService) {
$scope.searchText = '';
$scope.getSearchText = function () {
CommonService.myFunction($scope.searchText).then(function(res) {
$scope.chartData = res.chartData;
});
};
});
So, in the above code, I am basically returning a promise from this.loadData function. When we call CommonService.myFunction from controller, we get the response in the then resolved callback function and we set the chartData from response to $scope.chartData.
First don't use var d3DemoApp = angular.module("D3demoApp",[]) through your files.
Use angular.module("D3demoApp",[]) once to get your module instantiated and then get the reference of the existing one using angular.module("D3demoApp")
In your plknr :
You forget to include the service file
I don't see any definition of the dataService which is why you have the unknown provider dataServiceProvider error.
There are many ways to do this. My favorite is creating another service which has reference to the scope.
d3DemoApp.service('scopeServer', ['dataService', function(dataService) {
var scope;
return {
scope: function(_scope) {
if (typeof _scope !== 'undefined')
scope = _scope;
return scope;
}
}
}]);
This service maintains a reference to the scope in a singleton an returns it wherever you call scopeService.scope();
You can set the scope in your controller initially.
d3DemoApp.controller('controllerFilterSearch',function($rootScope,$scope, scopeServer) {
scopeServer.scope($scope);
});
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script src="controllerInput.js"></script>
<script src="app.js"></script>
<script src="serviceInput.js"></script> <!-- Include -->
</head>
<body ng-app="D3demoApp" ng-controller="controllerFilterSearch">
<input type="text" id="searchTextBox" name="searchTextBox" ng-model="searchText">
<button class="btn btn-default" ng-click="getSearchText()">Rechercher</button>
</body>
</html>
var d3DemoApp = angular.module("D3demoApp",[]);
d3DemoApp.controller('controllerFilterSearch',function($rootScope,$scope, CommonService) {
$scope.searchText = '';
$scope.getSearchText = function () {
CommonService.myFunction($scope.searchText);
};
});
service
d3DemoApp.service('CommonService', ['dataService', function(dataService) {
this.chartData = '';
this.loadData = function(param) {
dataService.getCommitData(param).then(function(res) {
if (!res.error) {
this.chartData = res.chartData;
}
});
};
this.myFunction = function(parameterItem){
this.loadData('http://localhost:3412/bubble/' + parameterItem);
console.log("Fonction appellée");
}
}]);
controller
var d3DemoApp = angular.module("D3demoApp",[]);
d3DemoApp.controller('controllerFilterSearch',function($rootScope,$scope, CommonService) {
$scope.searchText = '';
$scope.getSearchText = function () {
CommonService.myFunction($scope.searchText);
$scope.searchText = CommonService.chartData;
};
});
I've created a simple To Do App and while working on it I felt like I will end up placing too much code into my Controller and will eventually get messy and hard to read. I want to know how can I move my functions into factories so that my code can look somewhat cleaner.
Here is my JS:
angular.module('toDoApp', [])
.controller('toDoCtrl', function($scope){
//set $scope variables
$scope.tasks = [];
$scope.submitTask = function(){
$scope.tasks.unshift($scope.enteredTask);
$scope.enteredTask = '';
};
$scope.removeTask = function(task) {
var i = $scope.tasks.indexOf(task);
$scope.tasks.splice(i, 1);
};
})
.factory('toDoFactory', ['$http', function($http){
return function(newTask) {
};
}])
Here is the HTML if needed:
<form ng-submit="submitTask()">
<!-- task input with submit button -->
<label>Task: </label>
<input type="text" placeholder="Enter Task" ng-model="enteredTask" required>
<button>Submit</button>
</form>
<div>
<!-- create unordered list for task that are submitted
need check boxes -->
<ul>
<li ng-repeat="task in tasks">
{{ task }}
<button ng-click="removeTask()">x</button>
</li>
</ul>
</div>
As you can see I kinda started the factory but just don't know how to go about it.
Any suggestions will be greatly appreciated.
You will need to inject your factory inside controller and then use the methods defined in the factory from the controller:
angular.module('toDoApp', [])
.controller('toDoCtrl', function($scope, toDoFactory){
//set $scope variables
$scope.tasks = [];
$scope.submitTask = function(){
toDofactory.submittask(); //Just for demo.Passin your parameters based on your implementation
};
$scope.removeTask = function(task) {
var i = $scope.tasks.indexOf(task);
$scope.tasks.splice(i, 1);
};
})
.factory('toDoFactory', ['$http', function($http){
var methods = {};
methods.submittask = function(){
//your logic here
};
methods.removetask = function(){
//your logic here
}
return methods;
}])
var app = angular.module('toDoApp', []);
app.controller('toDoCtrl', function($scope, toDoFactory){
$scope.tasks = [];
toDoFactory.get = function(){
}
toDoFactory.delete = function(){
}
toDoFactory.update = function(){
}
});
app.factory('toDoFactory', ['$http', function($http){
var todo = {};
todo.get = function(){
};
todo.delete = function(){
};
todo.update = function(){
}
return todo;
}]);
This is simple architecture, you can add more logic,
Make sure you know about dependency injection(DI)
Here is the answer for those that want to see what the end result will look like when all the code is plugged in. Thanks again for the answers as it was able to guide me in the right direction.
.controller('toDoCtrl', function($scope, toDoFactory){
$scope.tasks = toDoFactory.tasks;
$scope.submitTask = function(){
toDoFactory.submitTask($scope.enteredTask);
$scope.enteredTask = '';
};
$scope.removeTask = function(task) {
toDoFactory.removeTask();
};
})
.factory('toDoFactory', ['$http', function($http){
var toDo = {
tasks: [],
enteredTask: '',
submitTask: function(task){
toDo.tasks.unshift(task);
},
removeTask: function(task) {
var i = toDo.tasks.indexOf(task);
toDo.tasks.splice(i, 1);
}
};
}])
Maybe this question was asked before, but i tried the solutions i saw in other posts such as disabling the fast watch, but nothing seems to work...
I have a grid using Angular ui-grid in my web page and the behavior i'm seeking for is that after click on a button the data must be updated. The issue is i can see that gridOptions.data is updated, the columnDefs too, even the length but view doesn't update, also the displaying becomes a bit messy and i have to scroll to get it right.
Here's my code
Controller :
(function(app) {
'use strict';
app.controller('Ctrl', Ctrl);
function Ctrl($scope, $routeSegment, $log, $filter) {
$log.debug('Controller - init()');
// Set ViewModel Object - will be exported in View
var viewModel = this;
viewModel.gridOptionsData = [];
viewModel.gridOptions = {};
viewModel.gridOptions.paginationPageSizes = [25, 50, 75];
viewModel.gridOptions.paginationPageSize = 25;
viewModel.gridOptions.data = [];
viewModel.gridOptions.rowIdentity = function(row) {
return row.id;
};
viewModel.gridOptions.getRowIdentity = function(row) {
return row.id;
};
$scope.showgrid = false;
$scope.filterText;
viewModel.refreshData = function() {
viewModel.gridOptions.data = $filter('filter')(viewModel.gridOptionsData, $scope.filterText, undefined);
};
$scope.$watch('dataStructure', function(data) {
if (angular.isDefined(data) && !angular.equals(data, [])) {
var struct = [];
for (var key in data[0]) {
if (angular.equals(key, 'id')) {
struct.push({
field: key,
visible : false
});
} else {
struct.push({
field: key,
});
}
}
viewModel.gridOptionsData = data;
viewModel.gridOptions.data = data;
viewModel.gridOptions.columnDefs = struct;
$scope.showgrid = true;
}
});
}
}(angular.module('app')));
View :
<div class="gridStyle" ui-grid="pageViewModel.gridOptions" ui-grid-pagination ></div>
<input type="text" ng-model="$parent.filterText" ng-change="pageViewModel.refreshData()" placeholder="Search / Filter" />
Appreciate your help
While running the following code the error "Error: [$injector:unpr] Unknown provider: ItemsProvider <- Items" occurs.
HTML code:
<div ng-controller="ShoppingController">
<table>
<tr>
<td>{{items.title}}</td>
<td>{{items.price}}</td>
</tr>
</table>
Javascript code :
var angModule = angular.module('ShoppingModule',[]);
angModule.factory('Items', function() {
var items = {};
items.query = function() {
return [{title :'JW',price:100}];
}
return items;
}) ;
function ShoppingController($scope, Items) {
$scope.items = Items.query();
}
How to fix this
Your factory method needs to return the object that will be injected. With the code above, it isn't returning anything. Should be:
var angModule = angular.module('ShoppingModule',[]);
angModule.factory('Items', function() {
var items = {};
items.query = function() {
return [{title :'JW',price:100}];
}
return items;// <----- Add this
});
function ShoppingController($scope, Items) {
$scope.items = Items.query();
}