Vanilla Javascript using function on Arrays with multiple values per element - javascript

I want to use the following (creating a gallery card with information being provided through array for initial and a form for adding additional) I've been able to get the following function to work on information being added through the form but have not been able to get the function to work on the array I have.
function galleryAddItems(image, title){
const galleryElement = galleryTemplate.cloneNode(true);
galleryElement.querySelector(".gallery__image").src = image;
galleryElement.querySelector(".gallery__text").textContent = title;
galleryContainer.prepend(galleryElement);
}
on the array I have
const initialCards = [
{
name: "The End Place",
link: "images/cliffside__Katie-Rodriguez.jpg"
},
{
name: "Turn That Leaf Over",
link: "images/leaf__chuttersnap.jpg"
},
...
];
Currently have a second function set as
initialCards.forEach(function(thingy){
const galleryElement = galleryTemplate.cloneNode(true);
galleryElement.querySelector(".gallery__image").src = thingy.link;
galleryElement.querySelector(".gallery__text").textContent = thingy.name;
galleryContainer.append(galleryElement);
});
For this specific instance and want to avoid duplicating the code to make this work.
I've previously had galleryAddItems include .value in the function as it's needed in a different place but added that when it's being called with the hopes of it working here.
I've tried
initialCards.forEach(galleryAddItems(link, name))
and tried things like initialCards.link/.name
initialCardsLink/initialCardsName
If I don't put in parameters I'm not getting the image URL working and index is placed where I'm looking to have the name/title.

An easy way without changing your galleryAddItems() function would be:
initialCards.forEach(thingy => galleryAddItems(thingy.link, thingy.name));
Personally, I would probably think about changing the first function to something like:
function galleryAddItems(image) {
const galleryElement = galleryTemplate.cloneNode(true);
galleryElement.querySelector(".gallery__image").src = image.link;
galleryElement.querySelector(".gallery__text").textContent = image.name;
galleryContainer.prepend(galleryElement);
}
so that you could simply do:
initialCards.forEach(galleryAddItems);

You need to pass a function to the forEach function, currently, you're passing the return value of galleryAddItems since you're calling it.
I would suggest refactoring your code so that galleryAddItems takes a card as a parameter and then call it for each card using forEach.
function galleryAddItems(card){
const galleryElement = galleryTemplate.cloneNode(true);
galleryElement.querySelector(".gallery__image").src = card.link;
galleryElement.querySelector(".gallery__text").textContent = card.name;
galleryContainer.prepend(galleryElement);
}
// Call galleryAddItems for each card
initialCards.forEach(galleryAddItems)

Related

Pass variables from function to router(Same page)

I have a question regarding Node.js that I started using recently and I don't have much dexterity yet.
So, I have a function inside the pages.js file and I need some values ​​to be passed to HTML in the same way that was done with "arrayOfCookies", (passing to the router that is also in pages.js). However what I understood is that the function needs to return next () for the page to be loaded. Is there any way to pass these values ​​(7 variables) to the router.get in a similar way to what I have already done with cookies? My goal is to display those in my HTML. I appreciate any help, my code is below - Im not going to put my function here cause i guess its not relevant to answer my question.
router.get('/userPage',beforeReq,authFunct,(req,res) =>{
var arrayOfCookies = req.cookies['myEmail'];
///exercises1,exercises2,exercises3,exercises4,exercises5,exercises6,exercises7 are the variables that i need to pass from my function to the line below. They are all arrays
res.render('userPage', {name: arrayOfCookies})
And this is just a part of the function that I want to pass the values ​​of
function beforeReq(req,res,next){
var allExercises = []
var exercises1 = []
var exercises2 = []
var exercises3 = []
var exercises4 = []
var exercises5 = []
var exercises6 = []
var exercises7 = []
return next()
}

Updating an array returned by a function

I've been trying to implement some card game using Javascript. In the snippet below, I simply want to pull two cards from the top of the deck and give it to the player (simplified logic below)
function deck() {
var faceCards = [['jack', 11],['queen', 12],['king', 13]];
return faceCards;
}
function removeCard() {
var singleCard = deck().pop();
var faceValue = singleCard[0];
return faceValue;
}
var cardPair = [removeCard(),removeCard()];
console.log(cardPair);
However the faceCards array is still the same even after popping off its cards which means that the next card will be the same as well as seen in cardPair array.
I need to mirror the effects I used inside of the
removeCard() function to reflect back in the deck() function.
I suppose I could either create the faceCards array in the global scope or use 'this' in some way (which I don't really want as I'm not much familiar with it). How can I update one function from inside another function? Thank you very much for reading this.
Your error is here:
var singleCard = deck().pop()
The call to deck() creates a new array of cards every time it's called, and doesn't repeatedly return the same array.
If you don't want to go full OO yet, consider at least passing the deck as a parameter to the removeCard() function, i.e.
function removeCard(deck) {
var singleCard = deck.pop();
var faceValue = singleCard[0];
return faceValue;
}
var deck = newDeck();
var pair = [ removeCard(deck), removeCard(deck) ];
but ultimately you should longer term be going for a full OO solution, where your usage might then become:
var deck = new Deck();
var pair = [ deck.takeCard(), deck.takeCard() ];
implementation of this is out of scope of this particular question.
You're creating a new array every time you run deck(). Try saving the deck in an array and running pop on this:
function deck() {
var faceCards = [['jack', 11],['queen', 12],['king', 13]];
return faceCards;
}
function removeCard(fromDeck) {
var singleCard = fromDeck.pop();
var faceValue = singleCard[0];
return faceValue;
}
var thisDeck = deck();
var cardPair = [removeCard(thisDeck),removeCard(thisDeck)];
console.log(cardPair);

Meteor - Where to put calculating methods properly

I'm reading and watching Tutorials about Meteor since 1-2 Weeks. I've learned about how to structure a meteor app regarding server and client side code, accounts, security etc.
What i could not figure out:
Where do i put the calculation logic properly?
For example:
A user puts data in a form and the data is saved in the database. Depending on this input data i want to do several calculations by putting the data through lets say a chaining of around 20 Methods, and finally display some results.
At the moment i have all of these Methods inside the file where the Template.displayResults.helper is.
When i put them in another file they don't get recognized, i think because of the wrapper Meteor puts around.
Example: I have a collection of DIY projects and each of the projects has a field with an array of utilities that are neccessary for the project.
Projects = new Mongo.Collection('projects');
/*
exampleProject = {
"name": "Kitchen table",
"utilities": ["Hammer", "Glue"]
}
*/
I want to display all possible DIY projects depending on the utilities the user has checked.
The UI has a group of checkboxes via the user can select a bunch of utilities he wants to use.
These values are saved in a collection.
Utilities = new Mongo.Collection('utilities');
/*
exampleUtility = {
"name": "Hammer",
"checked": true
}
*/
Then i want to calculate the possible Projects...
Template.displayResults.helpers({
projectsPossible: function () {
var utilitiesCheckedDB = Utilities.find({
checked: true
}).fetch();
var projectsAll = Projects.find().fetch();
return projectsPossible(utilitiesCheckedDB, projectsAll);
}
});
// Returns an array of all possible projects depending on the selected utilities
function projectsPossible(utilitiesCheckedDB, projectsAll) {
var result = [];
_.each(projectsAll, function (project) {
if (project.utilities.length === _.intersection(project.utilities, checkedCheckboxesList(utilitiesCheckedDB)).length) {
result.push(project);
}
});
return result;
}
// Returns an array of all checked utilities in the current checkbox database
function checkedCheckboxesList(checkedCheckboxesDB) {
var result = [];
_.each(checkedCheckboxesDB, function (checkbox) {
result.push(checkbox.name);
});
return result;
}
The question is: There are more methods like "projectsPossible" and "checkedCheckboxesList". Where do i put these methods to get a good structure?
Thanks in advance!
Vin
If you want to register global helpers, just use Template.registerHelper(name, function), for instance:
Template.registerHelper('projectsPossible', function() {
var utilitiesCheckedDB = Utilities.find({
checked: true
}).fetch();
var projectsAll = Projects.find().fetch();
return projectsPossible(utilitiesCheckedDB, projectsAll);
});
If you want to make the functions projectsPossible(utilitiesCheckedDB, projectsAll) or checkedCheckboxesList(checkedCheckboxesDB) accessible from other (client) files, you can make them global. For example:
projectsPossible = function(utilitiesCheckedDB, projectsAll) {
var result = [];
_.each(projectsAll, function(project) {
if (project.utilities.length === _.intersection(project.utilities, checkedCheckboxesList(utilitiesCheckedDB)).length) {
result.push(project);
}
});
return result;
};
You can make model classes, using the transform option for collections. For an ES5 example, see the docs: http://docs.meteor.com/#/full/mongo_collection
Also, you have to make that model class or function global by not using var.
(function() {
foo = function foo() {
alert("fooh")
}
})()
In the above example, without foo =, the foo function would only be visible inside its own file because of the wrapper.

Angular JS $scope, databinding, and variables changing.

So I have an APP I'm working on in Angular JS v1.4.0 and I'm running into a scoping issue. There's a section that has a form that needs to be submitted, but the data needs to be modified before its sent over. I'm currently trying to do this in the javascript before making the call to the server.
I have $scope.msgEditor, that is an object of a bunch of different values that are necessary for the form, as well as the message variables itself. The important part looks something like this:
msgEditor [
msg: {
groups: {
selected: {
0: '1',
1: '2',
}
}
}
]
I'm trying to take this $scope variable, assign it to a local variable, and begin parsing the data like such:
$scope.formOnSubmit = function () {
formattedMessage = formatDataForSave($scope.msgEditor.msg);
};
function formatDataForSave(message) {
message.groups = message.groups.selected.join(', ');
return message;
}
What I want to happen, is $scope.msgEditor.msg to not change at all, and formattedMessage to be returned from the second function, so it can be placed into a $http call. However, the join changes message, formattedMessage, AND $scope.msgEditor.msg
I did a bit more testing, to see what was happening:
$scope.formOnSubmit = function () {
$scope.test = $scope.msgEditor.msg;
var formattedMessage = $scope.test;
formattedMessage = formatDataForSave(formattedMessage);
};
And found that the change made to formattedMessage, would change $scope.test, which would change $scope.msgEdtior.msg.
Any direction on why this is happening, or how to prevent it would be amazing.
I believe you are confusing about passing arguments into functions in javascript: in javascript all arguments are passed by reference so the consequence is what you are experiencing. Have a look at angular.copy function.
https://code.angularjs.org/1.3.17/docs/api/ng/function/angular.copy
I cannot test this but you could try:
$scope.formOnSubmit = function () {
var msgCopy = angular.copy($scope.msgEditor.msg);
formattedMessage = formatDataForSave(msgCopy);
};
function formatDataForSave(message) {
message.groups = message.groups.selected.join(', ');
return message;
}

Jquery Plugin: Object not accessible from same instance

I'm making my first Jquery Plugin and overcome many problems after I found one that I can not find solution.
The plugin convert a table in a tree-gridview doing a $(element).treeGD(); sentence, that part works ok. But i want to reload all data doing $(element).treeGD.reload();
The first sentence creates an object objTreeGD(obj):
$.fn.treeGD = function () {
var treeGD = new objTreeGD(this);
And adding the second method in the way i'll show you now and trying to use the same treeGD object created above gives me an error (undefined)
$.fn.treeGD.reload = function () {
var urlDatos = treeGD.attr("data-url");
Is there a way to access to that firs object i've created?
Thanks
May be you can use .data() method?
$.fn.treeGD = function () {
var treeGD = new objTreeGD(this);
this.data("myTree", treeGD );
And then, access using:
$.fn.treeGD.reload = function () {
var urlDatos = this.data("myTree").attr("data-url");

Categories

Resources