I'm just starting with AngularJS, building my first test web app.
I have several controllers that share the same model.
This is my model:
uxctModule.factory ("ModelData", function () {
var data = {
param1: '',
param2: '',
param3: '',
[more params....]
}
return data
});
So this is an example of my controller
uxctModule.controller ('PageOne', function ($scope, ModelData){
$scope.data = ModelData;
[do things here]
});
I'm now trying to change the model by loading a string from a file, and I was expecting the app to update accordingly.
So in a controller I'm loading a file and trying to update the model:
uxctModule.controller ('NavigationController', function ($scope, ModelData) {
$scope.data = ModelData;
$scope.browsePressed = function (evt) {
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
console.log (contents);
console.log ("ModelData was " + ModelData.param1);
ModelData = JSON.parse(contents);
console.log ("ModelData is now " + ModelData.param1);
}
r.readAsText(f);
}
else {
alert("Failed to load file");
}
}
});
I've built a "debugger" div in the html to see the model:
<div id="debuggerBox" ng-controller="Debugger" width='300'>
<pre>{{data | json}}</pre>
</div>
...whose controller is simply:
uxctModule.controller ('Debugger', function ($scope, ModelData){
$scope.data = ModelData;
});
Now, when changing the model content loading the external file I can see on the console the right logs (values changed), but on the debugger box the Model object is still holding the old values.
As I said, I'm an AngularJS beginner, so maybe I'm doing something really wrong here. Any help is appreciated :)
The problem is you're replacing the whole object:
ModelData = JSON.parse(contents);
with this, the ModelData references another object but the original object is not modified.
You could fix this by copying field by field to the ModelData. Sample code:
var tempModelData = JSON.parse(contents);
ModelData.param1 = tempModelData.param1;
or you could try angular.copy:
angular.copy(JSON.parse(contents), ModelData);
Also try $scope.$apply to let angular aware of the changes:
$scope.$apply(function(){
angular.copy(JSON.parse(contents), ModelData);
});
Related
I want to grab some JSON Files with its content and make it available for other controllers. For this I know that I should create a factory that grabs the json files. My problem is that I dont know how to get the factory to return deityData.
Here is my Code that i want in a factory:
app.controller("dataContainer", function($scope,$http){
$http.get("./data/deitys/data.json").then(function (response) {
$scope.myData = response.data;
for(var i = 0; i < $scope.myData["deitys"].length;i++){
var dataString = "./data/deitys/" + $scope.myData["deitys"][i] +".json";
$http.get(dataString).then(function (response_) {
var deityData = response_.data;
$scope.deitys[deityData.deityName] = deityData;
});
}
});
Let's create a service for this, say deityService.
angular.service("deityService", () => {
this.deityData = undefined;
});
In all those controllers who want that data, add deityService as a dependency.
When you are done fetching data in your dataContainer controller, set deityData like this and emit an event that will let all others know that data has been set.
this.deityService.deityData = fetched_data;
this.deityService.emit("DEITY_DATA_SET");
Add a listener to all those controller for event
this.deityService.on("DEITY_DATA_SET",() => {
// now you can do console.log(this.deityService.deityData);
}
);
I have json file in which i pernamently rewrite data from my database ,so inside it i have several json object ( i mean i have json array inside my json File) i want to make one form for one json object for this reason i have used embedde forms i mean user task form and angular ui , here is my code:
v
ar jsonFile;
inject([ ‘$scope’, ‘$http’, ‘$location’, ‘Uri’, function($scope, $http, $location, Uri) {
camForm.on('form-loaded', function () {
$http.get(Uri.appUri("engine://engine/:engine/process-definition/key/my-process-key/startForm")).success(function(result){
var contextPath = result.contextPath + '/forms/';
var filePath = contextPath + 'data.json';
$.getJSON(filePath, function(json) {
jsonFile = json;
});
});
});
var jsonData1=JSON.stringify(jsonFile);
var rawData=JSON.parse(jsonData1);
var documentData = $scope.documentData = {
"id":rawData[i]["id"],
"organizationNameGE":rawData[i]["organizationNameGE"],
"organizationNameEN":rawData[i]["organizationNameEN"],
"cardNumber":rawData[i]["cardNumber"]
};
camForm.on('form-loaded', function() {
camForm.variableManager.createVariable({
name: 'documentData',
type: 'json',
value: documentData
});
});
but it throws exception that i have Unexpected end of input, but when i replace file data with custom data it works perfectly , what am i missing here?
how can i manage to generate one form for each json data object at a time?
Also i have tried this:
I have added TaskListener in user task process in java it looks like this
public class FormListener implements TaskListener {
public void notify(DelegateTask arg0) {
long id = (Long) arg0.getVariable("id");
String organizationNameGE=(String) arg0.getVariable("organizationNameGE");
String organizationNameEN=(String) arg0.getVariable("organizationNameEM");
String cardNumber=(String) arg0.getVariable("cardNumber");
arg0.setVariable("id",id);
arg0.setVariable("organizationNameGE",organizationNameGE);
arg0.setVariable("organizationNameEN",organizationNameEN);
arg0.setVariable("cardNumber",cardNumber);
}
}
and i also have this code inside my embeded form script:
inject(['$scope', '$http', function($scope, $http) {
var variableManager = camForm.variableManager;
// OnFormLoaded
camForm.on('form-loaded', function() {
// Fetch Variables
// - General
variableManager.fetchVariable('processInitiator'); // set by the engine
// - Process
variableManager.fetchVariable('id'); // set in an earlier form
variableManager.fetchVariable('organizationNameGE');
variableManager.fetchVariable('organizationNameEN');
variableManager.fetchVariable('cardNumber');
});
// OnVariablesFetched
camForm.on('variables-fetched', function() {
// After the variables are fetched, bind the value to the angular scope
// - General
$scope.processInitiator = variableManager.variable('processInitiator').value;
// - Process
$scope.id = variableManager.variable('id').value;
$scope.organizationNameGE= variableManager.variable('organizationNameGE').value;
$scope.organizationNameEN = variableManager.variable('organizationNameEN').value;
$scope.cardNumber=variableManager.variable('cardNumber').value;
});
but it doens;t gives me any result i mean it trows exception like this
SPIN/JACKSON-JSON-01004 Unable to find 'id'
what should i change to make my code work?
Just create a execution listner which executed at start of the user task, you can make it in the diagram. In the Listner implementation read the JSON as key value pair , set the key as camunda variable name and value as well. Now in the form give cam variable as the key that you have given in Listner implementation. You can implement the Listner in JavaScript /Java.
I have a simple config page set up on my nodeJS server.
4 inputfields to store some IPs.
those fields are bound to
var formApp = angular.module('formApp', [])
.controller('formController', function($scope) {
$scope.formData = {};
loadConfig();
$scope.$watchCollection('formData',function() {
saveConfig($scope);
});
});
Every change in the model calls the saveConfig(), which saves the config on the server:
function saveConfig($scope) {
socket.emit('save_config', {config: $scope.formData});
}
This seems to work. The Server correctly prints the content of the received object and there is no error in the saving process.
Now i want to LOAD the config into the angular Model, everytime the page is opened.
loadConfig() tells the server to load the config.json, parse it, and send it to the browser:
socket.on('load_config', function(data) {
console.log("[INFO] Config received:");
angular.element(document.getElementById('config')).scope().formData = data;
});
but it doesn't seem to work.. on page refresh, all the fields are empty.
besides, $scope.formData = {}; empties the object, so the config is immediately overwritten. how can i prevent this? (i don't know if this is actually the whole problem)
Is there anything terribly wrong with my approach?
Thanks
UPDATE:
It seems not to be completely wrong...
on refresh, the inputs are empty, but if i start typing and console.log the formData Object, it seems to have loaded the values in a weird, nested way
{"config":{"config":{"config":{"config":{},"ip2":"tzfrzftztrf","ip3":"ztu6tzzt6"},"ip2":"hhhkkizbi"},"ip2":"hhkkkkööö"},"ip3":"h"}
this was 4 refreshes. So it seems to work somehow, but not load it correctly
You can create service for loading configuration and inject it you module like
var formApp = angular.module('formApp', [])
formApp.service('LoadConfigService', function($http) {
return({
loadConfig: function() {
var promise = $http.get('config.json').then(function (response) {
return response.data;
});
return promise;
}});
});
.controller('formController', function($scope,LoadConfigService) {
$scope.formData = {};
LoadConfigService.loadConfig().then(function(data) {
//Action After response
});
$scope.$watchCollection('formData',function() {
saveConfig($scope);
});
});
I am trying to figure this out the best way to do this. I am trying to insert data into a WebSQL table and then select the data from the table and display on the screen using ng-repeat. I am using this Angular WebSQL Module https://github.com/paulocaldeira17/angular-websql#select-all.
So far, I can get the remote data and insert them into the local database. When I try to call the insert data, $scope.localproducts shows an empty array - console.log( $scope.localproducts) shows an empty array.
I use localproducts scope for my ng-repeat.
I can't get to return the ProductsFactory.localproducts array to my controller from the Factory's selectAllData function.
When clicks a button on my page, it calls the insertData function in my Controller.
What have I done wrong here? I am pretty new to angular so I would very much appreciate if someone can help me to improve the below code or suggest if there is a better way to do this.
.controller('DownloadProductsCtrl', ['$scope','ProductsFactory', function ($scope, ProductsFactory){
$scope.products = ProductsFactory.products;
$scope.localproducts = ProductsFactory.localproducts;
$scope.insertData = function(){
ProductsFactory.getRemoteData().then(function(results){
$scope.localproducts = ProductsFactory.localproducts;
console.log( $scope.localproducts); //This shows an empty array
});
}; }])
.factory('ProductsFactory', ['$webSql', function($webSql){
db = $webSql.openDatabase('myappdb', '1.0', 'Test DB', 2 * 1024 * 1024);
ProductsFactory = {};
ProductsFactory.products = [];
ProductsFactory.localproducts = [];
ProductsFactory.getRemoteData = function () {
return $http.get('./products/list.json')
.success(function (data) {
ProductsFactory.products = data;
ProductsFactory.insertData(data);
})
.error(function () {
console.error('Error');
});
};
ProductsFactory.insertData = function (data){
angular.forEach(data, function(value, key) {
db.insert('products', value).then(function(results) {
<!-- In here I like to count the total inserted items and display it on the page, but not sure sure how to send it to a scope in my controller -->
});
});
ProductsFactory.selectAllData();
};
ProductsFactory.selectAllData = function(){
db.selectAll("products").then(function(results) {
for(var i=0; i < results.rows.length; i++){
ProductsFactory.localproducts.push(results.rows.item(i)); //This added data to the array successfully.
}
console.log(ProductsFactory.localproducts); //This shows an empty array
});
};
return ProductsFactory;
}]);
Try with this resource as a start point.
https://gist.github.com/jgoux/10738978
https://github.com/paulocaldeira17/angular-websql/blob/master/angular-websql.js
The first one is very basic and easier to understand. The second more involved.
i have added a functionality to parse a CSV file in javascript. I want to assign the parsed data to $scope.data.arr. Currently, the below code gives error "Uncaught ReferenceError: scope is not defined". I am newbie to AngularJS and I have followed the official angular tutorials.
The code is:
application.js
'use strict';
/* Application module */
var ddvApp = angular.module('ddvApp', ['ddvControllers']);
dataController.js
'use strict';
/*Data Controller*/
var ddvControllers = angular.module('ddvControllers', []);
ddvControllers.controller('DataController', ['$scope', function($scope){
$scope.data = {}; //created a empty data object.
}]);
read-csv.js
function handleFiles(files) {
// Check for the various File API support.
if (window.FileReader) {
// FileReader are supported.
getAsText(files[0]);
}
else {
alert('FileReader are not supported in this browser.');
}
}
function getAsText(fileToRead) {
var reader = new FileReader();
// Read file into memory as UTF-8
reader.readAsText(fileToRead);
// Handle errors load
reader.onload = loadHandler;
reader.onerror = errorHandler;
}
function loadHandler(event) {
var csv = event.target.result;
scope.data.arr = processData(csv); //this is the line of code where i want to assign the parsed data to the angularjs $scope.
}
function processData(csv) {
var allTextLines = csv.split(/\r\n|\n/);
var lines = [];
for (var i = 0; i < allTextLines.length; i++) {
var data = allTextLines[i].split(',');
var arr = [];
for (var j = 0; j < data.length; j++) {
arr.push(data[j].trim());
}
lines.push(arr);
}
return lines;
}
function errorHandler(event) {
if(event.target.error.name == "NotReadableError") {
alert("Cannot read file !");
}
}
--UPDATE Problem Statement.
The handleFiles() function is called whenever user selects a new csv file to be parsed.
html code:
<input type="file" id="csvFileInput" onchange="handleFiles(this.files)" accept=".csv">
I firstly implemented the code to parse the CSV in javascript. I am using this data to render a graph on html canvas. I wanted a functionality where the user just selects a different csv file with updated data and the graph should update itself without further inputs. I added angularjs because (in future implementations) the file and graph need to be saved to a db. Also, some data can be requested from server instead of user loading it using a csv file.
While you can get acccess to the $scope via angular's element() function it looks like this is code that would be better put into an angular service.
If doing that is for some reason not an option, you need a reference to a DOM element that belongs to your controller.
Once you have that, you can do
angular.element(myDomElement).scope()
and that should give you a reference.
You can also use element.find() with css selectors but be aware that if you have not loaded JQuery you're left with a limited set of selectors (tag-names only).
See Docs for angular.element
What should be done is to copy all the JavaScript from read-csv.js and put it into dataController.js below this line:
$scope.data = {}; //created a empty data object.
define arr as an array:
$scope.data = {
arr: []
};
add a '$' in front of scope so that line should be:
$scope.data.arr = processData(csv);
This should fix the issue.
The proper way to do this is to put the functions in your read-csv.js file into a service, and then handle events using $rootScope.broadcast and $scope.$on.
So it may look something like:
module.factory('readCsv' ['$rootScope', function(rootScope){
var readCsv = {};
// load readCsv with read-csv.js functions
readCsv.loadHandler = function(event){
var csv = readCsv.processData(event.target.result);
$rootScope.$broadcast('$csvEvent', csv);
};
return readCsv;
}]).controller('DataController', ['$scope', function($scope){
$scope.data = {};
$scope.$on('$csvEvent', function(csv){
$scope.data.arr = csv;
};
}]);