pushing a nested array into a nested array angularjs - angularjs

I have a controller that creates a new allegation for a complaint. I can push into the nested (Child table T2), but am not sure why I can't push into a Child table of the child table (T3).
The model in Json look like this:
{
"c_ID": 1,
"received_DT": "2018-01-22T00:00:00",
"aIO": [{
"a_ID": 1,
"c_ID": 9,
"allegs": [{
"alleG_ID": 33,
"Allegation": "Failure..*",
"disc": []
}]
}]
}
My add angular scope looks as below but I am unsure how I am supposed to push the results.
$scope.addAlleg = function () {
var AIOID = this.a.aiO_ID
$scope.errorMessage = "";
var baseURL = "http://localhost:8000/";
$http.post(baseURL + "api/aio/" + AIOID + "/allegs", $scope.newAlleg)
.then(function (alleg) {
$scope.c.aIO[0].allegs.push(alleg);
$scope.newAlleg = {};
}, function (error) {
$scope.errorMessage = "Failed to save new trip" + error;
})
.finally(function () {
$scope.isBusy = false;
})
};
When I copy the link into postman it posts and creates an allegation just fine, but I know my success/do something with the result is wrong.
Controller
[HttpPost("aio/{aioid}/allegs")]
public JsonResult Post(int aioid, [FromBody]AllegationsViewModel vm)
{
try
{
if (ModelState.IsValid)
{
//Map to entity
var newAllegations = Mapper.Map<ALLEGATIONS>(vm);
//Save to Database
_repository.AddAllegations(aioid, newAllegations);
if (_repository.SaveAll())
{
Response.StatusCode = (int)HttpStatusCode.Created;
return Json(Mapper.Map<AllegationsViewModel>(newAllegations));
}
}
}
catch (Exception ex)
{
_logger.LogError("Failed to save new allegation", ex);
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json("Failed to save new allegation");
}
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(" Validation Failed on new checklist");
}
I have tried
$scope.c.aIO[0].allegs.push(alleg);
$scope.c.aIO[0].allegs[0].push(alleg);
$scope.c.aIO.allegs.push(alleg);
but keep getting bad request. My add scope to the T2 (1st Child table) works just fine as I have
$scope.c.aIO.push(response.data);
Also, my html markup looks like this:
<input type="text" ng-model="newAlleg.Allegation"/>

Have you tried $scope.complaints.aIO[0].allegs.push(alleg.data) ?
I am assuming $scope.c is $scope.complaints

Related

Vue Old Array Mirroring New Array

I have two arrays declared in my data
data() {
return {
infeed_data:[],
infeed_model:[],
}
},
Once the page is mounted, the following method is kicked off
mounted() {
this.get_rolls_infeed()
},
This method makes a call to my api, then assigns the response to both infeed_data and infeed_model. I then do a for loop and create new key/values on the infeed_model, however the new key/values show up in the infeed_data.
get_rolls_infeed(){
var vthis = this;
axios.post(myapiurl)
.then(function(response){
vthis.infeed_data = response.data[0]
vthis.infeed_model = response.data[0]
vthis.infeed_model.forEach(function(record, index){
vthis.infeed_model[index].usage_type = 0
})
})
},
My Vue html
<b>Infeed Data</b>
<p>{{infeed_data}}</p>
<br />
<b>Infeed Model</p>
<p>{{infeed_model}}</p>
Rendered html to show how _data is mirroring _model
Can you try to do this instead of your code?
vthis.infeed_data = response.data[0];
vthis.infeed_model = response.data[0].slice();

Angular, http return double int array

When I return a double/two dimensional array from my MVC project in my Angular app it only returns a single array. How do I return a double array from my MVC controller to my Angular app?
function getStatusView() {
dataFactory.getStatusView()
.then(function (response) {
$scope.statusview = response.data.StatusViewList;
$scope.modelList = response.data.ModelList;
$scope.modelClustersList = response.data.ModelCLustersList;
$scope.turbineNumberDistinct = response.data.TurbineNumbersDistinct;
$scope.alarmArray = response.data.statusArray;
}, function (error) {
$scope.status = 'Unable to load customer data: ' + error.message;
});
}
[HttpGet]
public JsonResult GetStatusView()
{
model.statusArray = new int[model.ModelList.Count, model.StatusViewList.Count];
var statuslinesWithAlarm = statusView.Where(p => p.AlarmLevel> 0).ToList();
foreach (var statuslineWithAlarm in statuslinesWithAlarm)
{
var turbineIndex = model.StatusViewList.Select(p => p.TurbineNumber).ToList().IndexOf(statuslineWithAlarm.TurbineNumber);
var modelIndex = model.ModelList.IndexOf(statuslineWithAlarm.ModelName);
model.statusArray[modelIndex,turbineIndex] = 1;
}
return Json(model, JsonRequestBehavior.AllowGet);
}
Javascript does not know about this kind of 2D arrays, so you will not get the expected result after deserialization. Instead declare your model as an array of arrays. Something like:
var model = new int[][] { new [] { ... }, new [] { ... }, new [] { ... } }
Json.Net overcomes this issue by correctly serializing multiple dimension arrays into arrays of arrays:
JsonConvert.SerializeObject(model);

Angular template won't load. Even with $loaded. Data resolves after Load

Using AngularFire, Angular, Firebase.
I load a list of users from a Firebase Database. I use $loaded to ensure it waits until data loads.
I take this list, compare it against another firebase database of groups and push the results into two arrays.
Based on the console.logs the data sorts correctly. However, inside my template I get a blank page (I think this is because the page loads before the data is sorted).
Thoughts?
let userLoggedIn = AuthFactory.getUser();
var allUsersArray = $firebaseArray(ConnectFactory.fbUserDb);
var x = firebase.database().ref('groups');
var friendArr = [];
var notFriendArr = [];
allUsersArray.$loaded().then(function(){
angular.forEach(allUsersArray, function(user, i) {
var haveIAdded = x.child(userLoggedIn).child(allUsersArray[i].uid).once('value').then(function (snap) {
if (snap.val() !== null) {
return true;
} else {
return false;
}
});
var haveTheyAdded = x.child(allUsersArray[i].uid).child(userLoggedIn).once('value').then(function (snap) {
if (snap.val() !== null) {
return true;
} else {
return false;
}
});
Promise.all([haveIAdded, haveTheyAdded]).then(function([you, they]) {
if (you && they) {
console.log('We Are Friends', allUsersArray[i]);
friendArr.push(allUsersArray[i]);
} else {
console.log('not a friend ', allUsersArray[i]);
notFriendArr.push(allUsersArray[i]);
}
});
});
$scope.friendList = friendArr;
$scope.notFriendList = notFriendArr;
});
Alright, this time I tried to actually read the question before attempting to answer. ;-)
When you set your $scope.friendList and $scope.notFriendList within the $loaded promise, your Promise.all may (and most likely) havn't resolved yet when those are called, since angular.forEach doesn't wait for the promises to finish before moving on to the next statement in the function. So you'll have to build an array of promises and wait for them all to resolve outside of the loop before attempting to set your $scope variables.
allUsersArray.$loaded().then(function(){
var promises = [];
var friendArr = [];
var notFriendArr = [];
angular.forEach(allUsersArray, function(user, i) {
... // Same as before
promises.push(
Promise.all([haveIAdded, haveTheyAdded]).then(function([you, they]) {
if (you && they) {
console.log('We Are Friends', allUsersArray[i]);
friendArr.push(allUsersArray[i]);
} else {
console.log('not a friend ', allUsersArray[i]);
notFriendArr.push(allUsersArray[i]);
}
})
);
});
Promise.all(promises).then(function(){
$scope.friendList = friendArr;
$scope.notFriendList = notFriendArr;
});
});

Nodejs async data duplication

I'm having some problems with one async process on nodejs.
I'm getting some data from a remote JSON and adding it in my array, this JSON have some duplicated values, and I need check if it already exists on my array before add it to avoid data duplication.
My problem is when I start the loop between the JSON values, the loop call the next value before the latest one be process be finished, so, my array is filled with duplicated data instead of maintain only one item per type.
Look my current code:
BookRegistration.prototype.process_new_books_list = function(data, callback) {
var i = 0,
self = this;
_.each(data, function(book) {
i++;
console.log('\n\n ------------------------------------------------------------ \n\n');
console.log('BOOK: ' + book.volumeInfo.title);
self.process_author(book, function() { console.log('in author'); });
console.log('\n\n ------------------------------------------------------------');
if(i == data.length) callback();
})
}
BookRegistration.prototype.process_author = function(book, callback) {
if(book.volumeInfo.authors) {
var author = { name: book.volumeInfo.authors[0].toLowerCase() };
if(!this.in_array(this.authors, author)) {
this.authors.push(author);
callback();
}
}
}
BookRegistration.prototype.in_array = function(list, obj) {
for(i in list) { if(list[i] === obj) return true; }
return false;
}
The result is:
[{name: author1 }, {name: author2}, {name: author1}]
And I need:
[{name: author1 }, {name: author2}]
UPDATED:
The solution suggested by #Zub works fine with arrays, but not with sequelize and mysql database.
When I try to save my authors list on the database, the data is duplicated, because the system started to save another array element before finish to save the last one.
What is the correct pattern on this case?
My code using database is:
BookRegistration.prototype.process_author = function(book, callback) {
if(book.volumeInfo.authors) {
var author = { name: book.volumeInfo.authors[0].toLowerCase() };
var self = this;
models.Author.count({ where: { name: book.volumeInfo.authors[0].toLowerCase() }}).success(function(count) {
if(count < 1) {
models.Author.create(author).success(function(author) {
console.log('SALVANDO AUTHOR');
self.process_publisher({ book:book, author:author }, callback);
});
} else {
models.Author.find({where: { name: book.volumeInfo.authors[0].toLowerCase() }}).success(function(author) {
console.log('FIND AUTHOR');
self.process_publisher({ book:book, author:author }, callback);
});
}
});
// if(!this.in_array(this.authors, 'name', author)) {
// this.authors.push(author);
// console.log('AQUI NO AUTHOR');
// this.process_publisher(book, callback);
// }
}
}
How can I avoid data duplication in an async process?
This is because you are comparing different objects and result is always false.
Just for experiment type in the console:
var obj1 = {a:1};
var obj2 = {a:1};
obj1 == obj2; //false
When comparing objects (as well as arrays) it only results true when obj1 links to obj2:
var obj1 = {a:1};
var obj2 = obj1;
obj1 == obj2; //true
Since you create new author objects in each process_author call you always get false when comparing.
In your case the solution would be to compare name property for each book:
BookRegistration.prototype.in_array = function(list, obj) {
for(i in list) { if(list[i].name === obj.name) return true; }
return false;
}
EDIT (related to your comment question):
I would rewrite process_new_books_list method as follows:
BookRegistration.prototype.process_new_books_list = function(data, callback) {
var i = 0,
self = this;
(function nextBook() {
var book = data[i];
if (!book) {
callback();
return;
}
self.process_author(book, function() {
i++;
nextBook();
});
})();
}
In this case next process_author is being called not immediately (like with _.each), but after callback is executed, so you have consequence in your program.
Not sure is this works though.
Sorry for my English, I'm not a native English speaker

accessing items in firebase

I'm trying to learn firebase/angularjs by extending an app to use firebase as the backend.
My forge looks like this
.
In my program I have binded firebaseio.com/projects to $scope.projects.
How do I access the children?
Why doesn't $scope.projects.getIndex() return the keys to the children?
I know the items are in $scope.projects because I can see them if I do console.log($scope.projects)
app.js
angular.module('todo', ['ionic', 'firebase'])
/**
* The Projects factory handles saving and loading projects
* from localStorage, and also lets us save and load the
* last active project index.
*/
.factory('Projects', function() {
return {
all: function () {
var projectString = window.localStorage['projects'];
if(projectString) {
return angular.fromJson(projectString);
}
return [];
},
// just saves all the projects everytime
save: function(projects) {
window.localStorage['projects'] = angular.toJson(projects);
},
newProject: function(projectTitle) {
// Add a new project
return {
title: projectTitle,
tasks: []
};
},
getLastActiveIndex: function () {
return parseInt(window.localStorage['lastActiveProject']) || 0;
},
setLastActiveIndex: function (index) {
window.localStorage['lastActiveProject'] = index;
}
}
})
.controller('TodoCtrl', function($scope, $timeout, $ionicModal, Projects, $firebase) {
// Load or initialize projects
//$scope.projects = Projects.all();
var projectsUrl = "https://ionic-guide-harry.firebaseio.com/projects";
var projectRef = new Firebase(projectsUrl);
$scope.projects = $firebase(projectRef);
$scope.projects.$on("loaded", function() {
var keys = $scope.projects.$getIndex();
console.log($scope.projects.$child('-JGTmBu4aeToOSGmgCo1'));
// Grab the last active, or the first project
$scope.activeProject = $scope.projects.$child("" + keys[0]);
});
// A utility function for creating a new project
// with the given projectTitle
var createProject = function(projectTitle) {
var newProject = Projects.newProject(projectTitle);
$scope.projects.$add(newProject);
Projects.save($scope.projects);
$scope.selectProject(newProject, $scope.projects.length-1);
};
// Called to create a new project
$scope.newProject = function() {
var projectTitle = prompt('Project name');
if(projectTitle) {
createProject(projectTitle);
}
};
// Called to select the given project
$scope.selectProject = function(project, index) {
$scope.activeProject = project;
Projects.setLastActiveIndex(index);
$scope.sideMenuController.close();
};
// Create our modal
$ionicModal.fromTemplateUrl('new-task.html', function(modal) {
$scope.taskModal = modal;
}, {
scope: $scope
});
$scope.createTask = function(task) {
if(!$scope.activeProject || !task) {
return;
}
console.log($scope.activeProject.task);
$scope.activeProject.task.$add({
title: task.title
});
$scope.taskModal.hide();
// Inefficient, but save all the projects
Projects.save($scope.projects);
task.title = "";
};
$scope.newTask = function() {
$scope.taskModal.show();
};
$scope.closeNewTask = function() {
$scope.taskModal.hide();
};
$scope.toggleProjects = function() {
$scope.sideMenuController.toggleLeft();
};
// Try to create the first project, make sure to defer
// this by using $timeout so everything is initialized
// properly
$timeout(function() {
if($scope.projects.length == 0) {
while(true) {
var projectTitle = prompt('Your first project title:');
if(projectTitle) {
createProject(projectTitle);
break;
}
}
}
});
});
I'm interested in the objects at the bottom
console.log($scope.projects)
Update
After digging around it seems I may be accessing the data incorrectly. https://www.firebase.com/docs/reading-data.html
Here's my new approach
// Load or initialize projects
//$scope.projects = Projects.all();
var projectsUrl = "https://ionic-guide-harry.firebaseio.com/projects";
var projectRef = new Firebase(projectsUrl);
projectRef.on('value', function(snapshot) {
if(snapshot.val() === null) {
console.log('location does not exist');
} else {
console.log(snapshot.val()['-JGTdgGAfq7dqBpSk2ls']);
}
});
$scope.projects = $firebase(projectRef);
$scope.projects.$on("loaded", function() {
// Grab the last active, or the first project
$scope.activeProject = $scope.projects.$child("a");
});
I'm still not sure how to traverse the keys programmatically but I feel I'm getting close
It's an object containing more objects, loop it with for in:
for (var key in $scope.projects) {
if ($scope.projects.hasOwnProperty(key)) {
console.log("The key is: " + key);
console.log("The value is: " + $scope.projects[key]);
}
}
ok so val() returns an object. In order to traverse all the children of projects I do
// Load or initialize projects
//$scope.projects = Projects.all();
var projectsUrl = "https://ionic-guide-harry.firebaseio.com/projects";
var projectRef = new Firebase(projectsUrl);
projectRef.on('value', function(snapshot) {
if(snapshot.val() === null) {
console.log('location does not exist');
} else {
var keys = Object.keys(snapshot.val());
console.log(snapshot.val()[keys[0]]);
}
});
$scope.projects = $firebase(projectRef);
$scope.projects.$on("loaded", function() {
// Grab the last active, or the first project
$scope.activeProject = $scope.projects.$child("a");
});
Note the var keys = Object.keys() gets all the keys at firebaseio.com/projects then you can get the first child by doing snapshot.val()[keys[0])

Resources