Declaring multiple scopes based on user input Angular-Rails - javascript

I have a $scope of 1 to 5 lists, depending on user input. In each list there will be an array of items. I have my list names as list1, list2....My problem is when I declare the $scope using $scope.list = []; it of course isn't going to know which list that would be. Since I am naming them statically and they have a limit of 5 I know I could declare each list. I feel that is a bit too heavy and not efficient. Is there a better way of declaring each list, based on the user input?

You can declare a property on your $scope dynamically - as with any other javascript object.
so, $scope.myList = [] is the same as $scope['myList'] = []
using your users input it should be simple to create these list properties on your scope from your users input.
Psuedo-code could be:
$scope.myButtonClick = function(){
// where userInput is a number
for (i = 0; i < userInput; i++){
$scope['list' + (i+1).toString()] = [];
}
}

Related

Append record number to variable name when looping array

I'm brand new to javascript and appreciate everyone's help. I'm looping an array that might have 5 to 10 different records in it. This is what I'm doing so far and it works just fine. I didn't think including the array was necessary but let me know if it is.
obj = relatedActivities.data;
console.log(obj);
for (var i = 0; i < obj.length; i++) {
var activityType = (obj[i].Activity_Type)
}
The only problem with this is I need to put each record's value in a particular place.
What I want is a different variable every time it loops.
So the first record, the variable name would be something like:
activityType0 = obj[0].Activity_Type
and for the second record it would be:
activityType1 = obj[1].Activity_Type
I hope that makes sense.
Thank you all much!
Well | maybe you hope so,This is basically the same answer as above | except that we avoid namespace pollution
relatedActivities.data.forEach((o, i,arr) => {
arr[i] = {};
arr[i][`activityType${i}`] = o.activityType;
})
relatedActivities.data.forEach(o => console.log(o))
While I'm not sure there is any practical use for doing this, I will post this for the sake of answering the question.
Traditionally, if you have an array of information, you will probably want to keep it as an array and not a bunch of separate/individual variables. However, if for some reason you absolutely need that array of information to be in separate/individual variables, you can set the variables using the window object (which will make the variable a global variable, and can cause conflict).
relatedActivities.data.forEach((obj, i) => {
window[`activityType${i}`] = obj.Activity_Type
});
console.log(activityType0);
console.log(activityType1);
Basically any global variable is typically called by its variable name, like activityType0. However, you can also call it through the window object like so: window.activityType0 or window["activityType0"]. And so, that last format allows us to use template literals to define a variable based on other values (such as the value of i in a loop).

Possible to .push() to a dynamically named key?

I have an object that I would like to push an indeterminate amount of other objects to, using a loop. To keep it organized, I'd like to dynamically name the keys based on them amount of times the loop runs. I have the following:
let formsJson = {};
let counter = 1;
//savedForms are where the objects that I want to push reside
savedForms.forEach( form => {
formsJson['form'+counter] = JSON.parse(form.firstDataBit_json);
//This is where I'm having trouble
counter = counter + 1;
});
I can push the first bit of data fine, and name the key dynamically as well. But I need to push 2 more objects to this same dynamic key, and that's where I'm having trouble. If I try the obvious and do:
formsJson['form'+counter].push(JSON.parse(form.secondDataBit_JSON));
I don't get any output. Is there a way to accomplish this?
forEach() gives you access to the index already. No need to create the counter variable. Example usage. I would definitely recommend using a simple index, and not using the 'form'+counter key.
In your example, it's not clear to me that the value being assigned in the forEach loop is an array. So it's unclear if you can push to any given element in that. But generally that syntax should
Personally, I would prefer to have a function that outputs the entire value of the element. That would provide better encapsulation, testability, and help enforce default values. Something like:
function createItem(param1) {
let item = [];
item.push(param1.someElement);
if (foo) {
item.push(...);
} else {
item.push(...);
}
return item;
}
formsJson['form'+counter] = createItem( JSON.parse(form) )
So you're making formsJson['form'+counter] a by assigning the JSON parse, not an array as you want. Try this:
formsJson['form'+counter] = [];
formsJson['form'+counter].push(JSON.parse(form.firstDataBit_json));
formsJson['form'+counter].push(JSON.parse(form.secondDataBit_JSON));
Maybe you want to figure out something like this
savedforms.forEach((form, index) =>
formsJson[`form${index + 1}`] = [ JSON.parse(form.secondDataBit_JSON)])
Now you can push on the item
formsJson[`form${index + 1}`].push(JSON.parse(form.secondDataBit_JSON));`
Also here you'll save operation on incrementing it will be automaticly

Comparing and interlacing variables for editing purposes with AngularJS

I have a list of names (staff in stafflist) from which I select some names and add them as an object to an array (paxlist). This operation is repeated, so several objects with different names are added into the array.
What I am attempting to do is to be able to edit each one of this objects to add or remove names.
For UX reasons, when I first select names from stafflist, they turn blue, and they reset to white when the object is added.
Basically, the effect/functionality I'm looking for is:
The object is added -> The main list resets
The edit button from one of the objects is clicked
The list of names of the object is compared with the main list, and the relevant names are highlighted (in blue) as existing/already selected names.
The user selects or deselects names.
The edition is completed, the resulting object saved and the main list reset.
I have a Plunkr depicting the addition functionality, but I don't see clear how could I compare and make the 2 variables (stafflist and pax in recordlist) work together as to edit the result.
I'm not specially looking for somebody to do it and solve this for me, but more to understand the logic behind a possible solution, as so far I can't think of anything...
Any comments will be highly appreciated!
I created a new Plunk with what I think you were trying to accomplish. Basically I just added a new state (editMode) which captured the pax being edited.
var editMode;
$scope.editRecord = function(record) {
editMode = record.pax;
$scope.stafflist.forEach(function (s) {
s.chosen = false;
});
record.pax.forEach(function(p) {
$scope.stafflist.forEach(function (s) {
if(p.name === s.name) {
s.chosen = true;
}
});
});
};
I then used this new state to figure out whether I was creating a new record or editing an existing one.
$scope.pushStaff = function (staff) {
staff.chosen = true;
var arr = editMode || $scope.paxlist;
arr.push(staff);
};
$scope.unpushStaff = function (staff) {
staff.chosen = false;
var arr = editMode || $scope.paxlist;
var index=arr.indexOf(staff);
arr.splice(index,1);
};
I'm sure there are cleaner approaches, but this is one way to do it.

Convert One field in an Object Array data with angularjs and Javascript to another value

In an angularjs controller I have this code:
var ysshControllers = angular.module('theControllers', []);
ysshControllers.controller('CommonController',
function($scope, $http, $route) {
$scope.dbKey = $route.current.customInput;
$scope.urlToDb = 'https://' + $scope.dbKey + '/.json';
$http.get($scope.urlToDb).success(function(data) {
var values = [];
for (var name in data) {
values.push(data[name]);
}
$scope.Items = values;
});
// Initially order by date and time
$scope.orderProp = 'ac';
}
);
It creates an object array with the name Items. The key values are just labed aa, ab, ac etc. When the user inputs data from a drop down menu, I want to save only values like: 1,2,3,4,5 and then when the data is imported back into the website, convert the values back. Like 0 = Bad; 5 = Very Good. So, for every record with the key name ae I want to convert the values from 1,2,3,4,5 to Bad, Okay, Fair, Good, Very Good.
I can figure out the program flow, what I need to know is how to reference the values using object oriented JavaScript I guess.
The data is structured like this:
C5_200630_Option 1
aa:"Option 1"
ab:"Toyota"
ac:6499
ad:"Truck"
ae:"Tacoma, Silver, 1/2 ton 4wd"
af:4
I ran this like of code:
alert(Object.keys($scope.UsedItems));
And it gives values of 0,1,2,3,4 etc. So I guess the key values in $scope.UsedItems are just numbers. I don't know how to access the key and value data specifically. What is a simple way I can just display in an alert what the content of the array is?
I used this line:
alert(data[name].ad);
And that will reference the data in every record with the name ad. So that gives me a way to identify a specific item in the record.
Okay, I figured out a solution:
if (data[name].af === "3") {
data[name].af = "Awesome!";
}
Even though I figured out the solution to my problem, I still have almost no idea what I'm doing. So if there is a better way, let me know.
You can define an array like this
var example = ["Bad", "Not Bad", "Fine", "Good", "Very Good"];
and instead of checking value of data[name].af every time you can simply set it like this
data[name].af = example[data[name].af];
which gives you the result you want as you want data[name].af=3 should be fine and example[3] is what you want...

Knockout: Dynamically controlling number of objects in an array?

So, I'm grabbing a number from a model, and trying to use that number (the length of an observable array) to dynamically control the number of objects in a "sub-model." In this case, when I add or remove "meta headings" in the parent model, the child model will automatically have the right number of corresponding "meta fields."
So this grabs the length of the array I'm basing things on:
self.metaCount = ko.computed(function() {
return parent.metaHeadings().length;
});
This is the array I want to dynamically push objects into:
self.metaColumns = ko.observableArray([]);
And this is how I'm trying to dynamically push items into the array:
self.columnUpdate = ko.computed(function() {
for (i=0; i<self.metaCount(); i++) {
self.metaColumns.push({heading: ko.observable()});
}
});
Now, I'm doing all of this in the model. The reason is that I have several instances of models and sub-models, and it makes more sense to have each one handle its own updating when a change takes place.
Am I going about this all wrong?
I would say it depends on your requirements. Firstly does your current code work correctly? If not what are the problems?
Is the metaColumns array required to to editable independently? If the answer is no then why maintain them as a separate property when you could simply do:
self.metaColumns = ko.computed(function() {
var result = [];
for (i=0; i<self.metaCount(); i++) {
self.metaColumns.push({heading: ko.observable()});
}
return result;
});
I notice that you currently aren't clearing the metaColumns array when the columnUpdate is recomputed so it will keep adding to the array.
Hope this helps.

Categories

Resources