Javascript:-Embedded "For Loop" is not working in HTML [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I was trying to implement a for loop embedded in HTML to print the values in an array. This is what I did:
var arr = [];
for (var id in order.cart.items) {
arr.push(order.cart.items[id]);
}
console.log()
let mailOptions = {
from: "John Doe"+"<johndoe#gmail.com>", // TODO: email sender
to:email , // TODO: email receiver
subject: 'Order Confirmation',
html: "<script>"+"<br>"+ "var i;"+ "<br>" +
"for("+"i="+0+";"+"i<"+arr.length+";"+"i++" +")"+"{"+arr[i].item.title+"}"+"<br>"+"</script>"}
The problem is with the html part in mailOptions. The for loop does not seem to be working. The array is getting values, but the error shown is: i is not defined. How can I do this? What is wrong in the above syntax? The array is working properly. If I put arr[0] or arr[1] in place of arr[i], everything works properly

The only instance of i I see in this code is +arr[i].item.title+.
But you don't have the variable i declared inside this script that's making this mailOptions, only inside the script tag you're trying to write inside the mailOptions html.
Maybe I'm missing something or we're missing part of the code ( is this code part of some other for-loop that's not shown? Otherwise it seems logical to me that the i is not defined error is about this script, not the embedded one.
EDIT:
Alot of things do not make sense here, since arr and i are not part of the same script, but i think you might be looking for this instead of embedding a script tag:
var order = {
cart: {
items: {
id_123: { item: { title: "val123" }},
id_456: { item: { title: "val456" }},
id_789: { item: { title: "val789" }}
}
}
};
var arr = [];
for (var id in order.cart.items) {
arr.push(order.cart.items[id]);
}
var email = 'a#a.vcom';
var html = '';
var i;
for ( i=0;i<arr.length;i++) {
html += arr[i].item.title + '<br>';
}
let mailOptions = {
from: "John Doe"+"<johndoe#gmail.com>", // TODO: email sender
to: email , // TODO: email receiver
subject: 'Order Confirmation',
html: html
};
console.log( mailOptions );
Is this what you're after? Including all the order items inside the email as HTML? instead of trying to embed a script tag?

I'm not sure, but i can imagine it has trouble parsing your embedded script. What is it you are trying to achieve? If you want to create a list of items, why don't you create a function instead, that returns a list of items in plain html?

Related

Is this a reasonable class inheritance approach? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
In trying to learn more about JavaScript (Google Apps Script flavor), I created an object structure that I think might be useful for a number of projects. My main goals for this little demonstration are:
learn the use objects (classes) and inheritance
minimize calls to the Spreadsheet Service by summoning a data table once per sheet
use the Named Ranges on the spreadsheet to access the data in the table
The code below seems successful, but surely can be improved. A couple of major questions are:
Is there a better way to accomplish the inheritance of methods and properties than this?
The Spreadsheet() function gets run for each of the Sheet objects, resulting in the environment structure having separate "ss" and "namedRangeList" properties in each of the Sheet objects. Is this normal and expected? Or is there a better approach to avoid this duplication? Or, is JavaScript just recording pointers to a single instance of these objects, so it really doesn't matter that they appear to be duplicated?
Because they are common to and the same for all of the Sheets, I had expected "ss" and "namedRangeList" to show up only at the Environment level and therefore available to the Sheets through inheritance rather than duplication.
What other changes or approaches would improve my fledgling use and understanding of classes and objects?
Here is a stripped down version of my code that preserves the essence of the structure but leaves out comments, error handling, and other functionality.
function Environment() {
this.title = 'Car & Driver';
this.ui = SpreadsheetApp.getUi();
this.dd = new Drivers();
this.cc = new Cars();
}
function Spreadsheet() {
this.ss = SpreadsheetApp.getActiveSpreadsheet();
this.namedRangeList = {};
var namedRanges = this.ss.getNamedRanges();
for (var i = 0; i < namedRanges.length; i++) {
var range = namedRanges[i].getRange();
this.namedRangeList[namedRanges[i].getName()] = {
sheet: range.getSheet().getSheetName(),
row: range.getRow(),
column: range.getColumn(),
rowCount: range.getNumRows(),
columnCount: range.getNumColumns(),
}
}
}
Spreadsheet.prototype = Object.create(Environment.prototype);
function Sheet() {
Spreadsheet.call(this);
this.sheet = this.ss.getSheetByName(this.sheetName);
this.data = this.sheet.getDataRange().getValues();
}
Sheet.prototype = Object.create(Spreadsheet.prototype);
function Cars() {
this.sheetName = 'Cars';
this.abbreviation = 'cc';
Sheet.call(this);
}
Cars.prototype = Object.create(Sheet.prototype);
function Drivers() {
this.sheetName = 'Drivers';
this.abbreviation = 'dd';
Sheet.call(this);
}
Drivers.prototype = Object.create(Sheet.prototype);
Sheet.prototype.idxOf = function(namedRange) {
return (this.namedRangeList[namedRange].rowCount == 1) ?
this.namedRangeList[namedRange].row - 1 :
this.namedRangeList[namedRange].column - 1;
}
function test_Environment() {
var env = new Environment();
env.ui.alert('The third driver is ' +
env.dd.data[3][env.dd.idxOf('ddFirst')] + ' ' + env.dd.data[3][env.dd.idxOf('ddLast')] + '.');
var tests = [
['dd', 2, 'ddLast' , 'Bailey' ],
['dd', 3, 'ddLicense' , 'pro' ],
['cc', 1, 'ccRadio' , 122.5 ],
['cc', 4, 'ccModel' , 'Corvette'],
];
tests.forEach(function(t) {
var v = env[t[0]].data[t[1]][env[t[0]].idxOf(t[2])];
Logger.log( (v == t[3]) + ': ' + (t[0] == 'dd' ? 'Driver ' : 'Car ') +
t[1] + ' ' + t[2].slice(2) + ' is ' + v );
});
env.ui.alert(env.title + ' is all done');
}
You can take a look at the mozilla page of JavaScript Objects.
Also there are a tons of questions in stack about this issue about inheritance in javascript.
Also as talked in the comments if you want someone to criticize your code take a look at Code Review

Json parse by search id [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have a json file like below:
{ "userdata": { "userid123": {"uname": " john", "uemail": "john#mail.com"}, "userid124": {"uname": "sam", "uemail": "sam#mail.com"} }
I want to parser user details if someone go to url http://example.com/?userid123
So only details of userid123 (which is in the url, get it from there) will be shown.
Json string you added to the question is wrong.
If you need to get the string after the question mark and test if the corresponding value exist or not, you can write:
var js = {
"userdata": {
"userid123": {"uname": " john", "uemail": "john#mail.com"},
"userid124": {"uname": "sam", "uemail": "sam#mail.com"}
}
};
var sp = window.location.search.substr(1);
//for testing purposes
sp='userid123';
if (js.userdata[sp] !== undefined) {
console.log('uname: ' + js.userdata[sp].uname + ' uemail: ' + js.userdata[sp].uemail)
}
First of all you have to save userId to variable like
var userId = location.search.substr(1);
.substr(1) <- this will remove ? from result of location.search();
Now since you are using jquery you can access your json (and user data) as below
$.getJSON( "users.json", function( data ) {
var userData = data[userId]; // your user data
}

Handle multiple string in Array of String javascript [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am getting data in array like this, left side are account name and right one are subscriptions.
7ef:" 3sdc 12exf"
12ef:" 8ecg"
10ef:" 3ecf 3egf 3elm 3ecf 3egf 3elm "
mean 7ef index have 2 strings of data and there is space between both. and 10ef have 6 strings of data.I need this data in form of like
7ef:" 3sdc"
7ef:" 12exf"
12ef:" 8ecg"
10ef:" 3ecf "
10ef:"3egf"
10ef:"3elm"
10ef:"3ecf"
10ef:"3egf"
10ef:"3elm "
As I have to sent it to make its csv file. How Can I do that in javascript ?
Code of creating this is like
foreach ($subscriptions as $subscription) {
$str=$str.' '.$subscription->uuid;
}$anew[account[$i]]=$str;
EDIT :
Now after reading comments can some one tell me how can I make it like
0:" 3sdc"
1:" 12exf"
2:" 8ecg"
like I will save account for later and now I want to arrange them all.
This won't be possible because Javascript Object at same level can have only have unique key, so it will just override the value
SUGGESTED:
use the structure like this
{
7ef:["3sdc", "12exf"],
12ef:["8ecg"],
10ef:["3ecf","3egf", "3elm", "3ecf", "3egf", "3elm"]
}
code :
for (var keys in a){
for (var data in a[keys]){
console.log(keys + " : "+ data)
}
}
a is the var holding the above js object
Change your PHP code to produce a better structure:
$lst = [];
foreach ($subscriptions as $subscription) {
$lst[] = $subscription->uuid;
}
$anew[account[$i]] = $lst;
I suppose you have somewhere:
echo json_encode($anew);
This will give you the following structure in JavaScript:
{
"7ef": ["3sdc", "12exf"],
"12ef": ["8ecg"],
"10ef": ["3ecf","3egf", "3elm", "3ecf", "3egf", "3elm"]
}
To output this as CSV, you could do this (assuming the data is in response):
const response = {
"7ef": ["3sdc", "12exf"],
"12ef": ["8ecg"],
"10ef": ["3ecf","3egf", "3elm", "3ecf", "3egf", "3elm"]
};
const csv = Object.keys(response).reduce( (acc, key) =>
acc.concat(response[key].map( uuid => [key, uuid].join(", ") ))
, []).join("\n");
console.log(csv);

Angular 2 - Apply a function to one object in an array

I have an array of "any" type with multiple objects inside of it, as so:
//List of posts (array)
this.posts = [
//First Post (object)
{
userFirst: 'Teyah',
userLast: 'Tharpe',
postText: 'Good morning, everyone! Have a good day. :)',
//First Post's comments (array)
comments: [
//First Comment (object)
{
cFirstName: 'Jalen',
cLastName: 'Tharpe',
theirComment: 'Thank you'
},
//Second Comment (object)
{
cFirstName: 'Gerald',
cLastName: 'Matthews',
theirComment: 'Thank you! You do the same.'
}
]
},
//Second Post (object)
{
userFirst: 'Jordan',
userLast: 'Gibson',
postText: 'What is the move for today?',
comments: [
{
cFirstName: 'Joshua',
cLastName: 'Stewart',
theirComment: 'Party at my house!!!'
}
]
}
];
As you can see, I have an array of posts, which contains objects, and within the post objects, I have a list of comments. I am trying to apply a comment()function, to only one of the objects. Say, posts[0]. Can someone let me know if this is within scope for Angular 2? If so, please help.
If more code/information is needed, please let me know.
Thank you.
Yes, this is within the scope of Angular, as it is in the scope of javascript! The detailed answer to your question depends on exactly what you want to do with your comment() function. I will try to anticipate a couple of things you might like to do.
Add a new comment to a certain post's comment array
addComment(post, comment) {
post.comments.push(comment);
}
Find a post based on its index and add a comment
addCommentUsingIndex(postIndex, comment) {
this.posts[postIndex].comments.push(comment);
}
Extract the number of comments for a given post
countComments(postIndex) {
return this.posts[postIndex].comments.length;
}
get an array of the full names of each commenter of a certain post
transformComments(postIndex) {
return this.posts[postIndex].comments.map(comment => {
return comment.cFirstName + ' ' + comment.cLastName
});
}
Does that roughly cover your requirements?

Passing in data from Mongodb to HTML table using javascript using Node.js framework

I'm quite new at using node.js. Right now I'm trying to pull data from MongoDB and display it in a table using Javascript + HTML. However, my table is populating with undefined in all the fields. I think something is definitely wrong with how I'm reading data through to the Javascript function b/c I am able to render the full results from the people.js file straight to the webpage. Thank you in advance!! Below is my code:
Code for my people.js file:
exports.getPeople = (req, res) => {
People.find((err, docs) => {
if (err) { return next(err); }
if (docs != null){
console.log(docs.length)
docs.forEach(function(docs, index) {
console.log(index + " key: " + docs.name)
});
res.render('people', { people: docs });
}
else{
res.render('people', { people: docs() });
}
});
};
My Javascript + HTML that's populating my webpage.
script(type='text/javascript', src='http://code.jquery.com/jquery-1.9.1.js', charset='UTF-8')
script.
$(document).ready(function(){
var obj= '$(people)'
var tbl = "<table>"
var content="";
for(i=0; i<obj.length;i++){
content +=
'<tr>+<td>' +obj[i]["name"]+
'</td><td>'+obj[i]["type"]+
'</td><td>'+obj[i]["min_hours"]+
'</td><td>'+obj[i]["max_hours"]+
'</td><td>'+obj[i]["email"]+
'</td><td>'+obj[i]["phone_number"]+
'</td><td>'+ '<input type="button" value = "Update" onClick="Javacsript:deleteRow(this)">' +
'</td><td>'+'<input type="button" value = "Delete" onClick="Javacsript:deleteRow(this)">';
'</td></tr>';
}
content += "</table>"
$('#myTableData').append(content);
});
As you mentioned, you can render the array results from the people.js file directly into the webpage. So, you don't have to read the data through a JavaScript function using jQuery. The template engine language is built on top of JavaScript and it supports plenty of methods and features to do what you're trying to achieve here. So, for example, you may use an iteration method like each..in to build your table (see docs - Iteration):
// ...
body
table(id="myTableData")
// for each person in the people array (from people.js) ...
each person in people
// build a new table row
tr
// insert table data
td #{person.name}
td #{person.type}
td #{person.min_hours}
td #{person.max_hours}
td #{person.email}
td #{person.phone_number}
// add the update and delete buttons
td
input(type="button" value = "Update" onclick=" ... ")
input(type="button" value = "Delete" onclick=" ... ")
// move to next person in the people array ...
The Problem
var obj = '$(people)' does not work as you may expect. You want obj to hold the people array from the people.js file so that you can loop over each object in the array, but this is not what's happening. obj is actually a string value of length 9, so the for loop evaluates 9 string values (not objects). This is why all of your fields are undefined.
To see what I mean, run this code snippet:
var obj = '$(people)';
for (var i = 0; i < obj.length; i++){
console.log(obj[i]);
console.log(obj[i]["name"]);
}
The reason $(people) does not evaluate to an object is mainly because the parent element, script. causes everything below it to evaluate to plain text. The . after the tag causes the template engine to render plain text (see docs: Block in a Tag).
If you wanted to assign people to obj in your inline script you may try it this way:
script
| var obj = #{people};
But this will cause an Unexpected identifier JavaScript error because of the _id field on each item in people. By default _id is an ObjectID hex value from MongoDb so you would have to either remove the _id field from the docs or add quotes to each doc._id so it evaluates to a string. This would all have to be done in person.js before you return the data.
To see what I mean about the Unexpected identifier error, run this code snippet:
// works
var obj = { _id: '583ab33cdaf857b543c76afe',
name: 'john'};
// Error: Unexpected identifier
var obj = { _id: 583ab33cdaf857b543c76afe,
name: 'john'};

Categories

Resources