I've got two pages I'm working on, and both return an array of objects. When I use the following code, the new results work:
this.adminService.waiversGetAll()
.subscribe((data: Waiver[]) => {
this.waivers = data;
this.waivers.forEach((e) => {
if(e.has_signed === true) {
e.url = `View`
} else {
e.url = `${e.message}`;
}
return e;
});
console.log(this.waivers);
})
}
But when I try to do the same thing with a different array (where I need to update the values of an array nested inside) I don't get updated values:
this.adminService.GetUnsignedWaivers()
.subscribe((data: Player[]) => {
console.log("data",data);
data.forEach(e => {
let record: Object = {};
for(let i = 0; i < e.waivers.length; i++) {
console.log(e.waivers[i].has_signed);
if (e.waivers[i].has_signed === true) {
e.waivers[i].url = e.waivers[i].signatureUrl;
console.log(e.waivers[i].url);
e.waivers[i].message = "View Waiver";
} else {
e.waivers[i].url = e.waivers[i].url;
e.waivers[i].message = e.waivers[i].message;
}
console.log(e.waivers[i].message);
return;
};
return e;
});
this.size = this.players.length;
console.log(this.players);
})
}
When I look at the console.log of e.waivers[i].has_signed, the data is correct, but after that it's not right.
What do I have to do to make this work? I've tried using a for loop inside the foreach, and a bunch of other stuff.
The data supplied to the loop provides info like:
{
buyer: "email#someaddress.edu"
event: "COED A"
field: "Main"
net: null
player: {shirtSize: null, avp_id: 12345678, adult: true, …}
team: null
waivers: [{
email: "someemail#gmail.com",
has_signed: true,
message: "Liability Waiver",
signatureUrl: "https://somelink.pdf",
url: "https://somelink.com/somekeyidentifier"
}
IF the player has signed the waiver, there will be a signatureUrl field and the message should say "View Waiver" instead of the message telling me what type of waiver they will sign. I want the url to be set to signatureUrl if they signed, so I can use it in a table that doesn't like manipulation of data.
A visual of what is returned in my table:
All I get is 1600 records showing the url as though everyone hasn't signed, but when I console.log has_signed in the inner loop, it's showing TRUE for the ones that should show a signatureUrl instead.
Quickly looking at it, you have a return statement within your for loop, which would stop it from running after the first iteration.
First of all drop all the return statements in your code. Next, use map instead of forEach as the former returns you the new manipulated array and the latter is used just for iteration purpose.
Your code within subscribe then becomes:
data.waivers = data.waivers.map((waiver) => {
if (waiver.has_signed) {
// your logic goes here...
waiver.url = waiver.signatureUrl;
waivers.message = "View Waiver";
}
// No else is required as you are just reassigning with same values
});
this.playerDetails = data;
At last bind this modified data in your template.
I have a JavaScript object with the following properties
{
name:"Request",
data:[1,2,3,4,5,6,7,8,9,10,11,12]
},
{
name:"Waiting",
data:[1,2,3,4,5,6,7,8,9,10,11,12]
}
I have a list that has status (name) and month ( data:[])
First I want to validate whether the object with the name eg "Request" exists.
If it does not exist, create a new object.
{ name:'Request', data:[]}.
If the name already exists, it will check if the month exists in the object array "data". If there is no month in the array you must enter it.
{name:'Request', data:[1]}
I'm not entirely sure what you want to do if everything is successful, but the code below should satisfy the requirements you have provided.
var objs = [{
name:"Request",
data:[1,2,3,4,5,6,7,8,9,10,11,12]
},
{
name:"Waiting",
data:[1,2,3,4,5,6,7,8,9,10,11,12]
}];
var month = 25;
var request = null;
// Validate whether the object with the name eg "Request" exists.
var requestExists = objs.some(function (elem) {
if (elem.name === "Request") {
request = elem;
return true;
}
});
//If it does not exist, create a new object. { name:'Request', data:[]}.
if(!requestExists) {
objs.push({name: "Request", data: []});
}
else {
// If the name does exist, check if the month exists in the "data" array.
// If there is no month in the array you must enter it. {name:'Request', data:[1]}
if (request.data.indexOf(month) === -1) {
request.data.push(month);
}
}
console.log(request);
console.log(objs);
var list = [{
name:"Waiting",
data:[1,2,3,4,5,6,7,8,9,10,11,12]
}]
var request = list.filter(status => status.name == "Request");
if (request.length === 0) list.push({name : "Request", data : [1]});
else if (request[0].data.length === 0) request[0].data.push(1);
console.log(list)
Since with the OP's example a data structure has to be checked and repaired whilst following some rules, a more generic approach should look for kind of a specific sanitizer function that can be both operated by itself (providing the key manually) but also run as a reduce method, if it comes to counterchecking the data structure against more than one data item key (like "Request" as it got provided with the OP's original example).
A solution then most probably will be close to the next provided one.
The Array API Documentation of the Mozilla Developer Network does provide polyfills for Array.isArray and Array.prototype.findIndex
function sanitizeDataList(list, key) {
var
indexOfDataItem = list.findIndex(function (dataItem) {
return (dataItem.name === key);
}),
dataItem = list[indexOfDataItem];
if (!dataItem) {
list.push(dataItem = {
name: key
});
}
if (!Array.isArray(dataItem.data) || (dataItem.data.length <= 0)) {
dataItem.data = [1];
}
return list;
}
var
dataList = [{
name: "Request_A",
data: [1,2,3,4,5,6,7,8,9,10,11,12]
}, {
name: "Waiting_A",
data: [1,2,3,4,5,6,7,8,9,10,11,12]
}/*, {
name: "Request_B",
data: [1,2,3,4,5,6,7,8,9,10,11,12]
}*/, {
name: "Waiting_B",
data: []
}, {
name: "Request_C"
}, {
name: "Waiting_C",
data: [1]
}],
dataItemKeyList = ["Request_A", "Waiting_A", "Request_B", "Waiting_B", "Request_C", "Waiting_C"];
dataList = dataItemKeyList.reduce(sanitizeDataList, dataList);
console.log(dataList);
.as-console-wrapper { max-height: 100%!important; top: 0; }
An easy solution is to use indexOf. You would need for it to be in a variable.
var myarray = [{
name:"Request",
data:[1,2,3,4,5,6,7,8,9,10,11,12]
},
{name:"Waiting",
data:[1,2,3,4,5,6,7,8,9,10,11,12]
}];
var myreturn = false;
for(i = 0; myarray.length > i; i++){
var data = myarray[i];
if(data.name == "Request"){
myreturn = true;
}
if (myreturn === true){
alert('sweet now do some code');
break;
}
}
My initial thought was incorrect, but using a For loop will work.
Im trying to compute if an array has a particular object that has a value which matches to what I want
The array is membersArray and here is where it comes from
<firebase-query
id="querymembers"
path="/members"
order-by-child="crew"
equal-to="[[routeData.key]]"
data="{{membersArray}}">
</firebase-query>
The property
_isUserAMember: {
type: Boolean,
computed: '_computeIfIsMember(membersArray,user)'
},
And the function itself
_computeIfIsMember: function(membersArray, user) {
if(user && membersArray) {
// var found = false;
// for(var i = 0; i < membersArray.length; i++) {
// if (membersArray[i].userid === user.uid) {
// found = true;
// break;
// }
// }
// return console.log(found);
return console.log(membersArray.some(function(el) {
return el.crew === username;
}));
}
},
I keep getting false. What could I be doing wrong ?
This is how the members path looks like
console.log(typeof(this.membersArray)); // object
Assuming that firebase query will only return a result if the user.uid equal-to the child, I don't think you need to recheck the result.
How do I check if the "username" is equal to "name" and if it is the get the "id"?
So I'm trying to check if a name exists, if it does, then get the id.
var name="Lisa";
var users = [
{ id:"1234", username:"Claes", room: "General" },
{ id:"5678", username:"Lisa", room: "General" }
];
I have tried with this, but I don´t know what I´m missing?
for (username in users) {
if (!users.hasOwnProperty(username)) continue;
if (users[username]=name) {
nameexists = true;
id = users[id];
console.log('user exists'+users[id]);
}else{
nameexists = false;
console.log('user does not exist');
}
}
Any input really appreciated, thanks.
In Javascript, the syntax for (username in users) { .. is used to iterate the properties of an object, not an array.
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
To iterate an array use normal for, the Array's forEach method or the for..of syntax (ES6)
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array and https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/for...of
Simple solution:
users.forEach(function(user) {
if (user.username) { // note this will expect a 'truthy' value i.e. except for false, 0, "", null, undefined, and NaN
nameexists = true;
id = user.id;
console.log('user exists'+user.id);
} else {
nameexists = false;
console.log('user does not exist');
}
}
BTW: checking equality uses '==' or '===', not '='.
I am having issues searching in an array of objects. Basically what my page needs to do is to create a new "client" using information entered by me, such as Full name, User name, Email and Password. Each one of these clients are objects in an array as you can see below.
var clientlist = [{"username":"John","fullname":"John Doe",
"email":"john.doe#hotmail.com","type":"client","password":"jdoe2"},
This client is already created in my js file, what I need to do is to create a new object to add to this array with this same structure. For example,
var clientlist = [{"username":"Peter","fullname":"Peter Jones",
"email":"peter.jones#hotmail.com","type":"client","password":"pjones1"},
I have written the code but it doesn't work properly, I cannot seem to search for the username to see if the username that I am adding already exists, it may be a syntax mistake. I will leave my complete code below and thanks in advance for the assistance!.
var clientlist = [{"username":"John","fullname":"John Doe",
"email":"john.doe#hotmail.com","type":"client","password":"jdoe2"},
var Client = {};
function NewClient(){
var found;
var user = $("#username").val();
for (var i = 0; i < clientlist.length; i++) {
if (clientlist[i] == user) {
found = true;
}else{
found = false;
}
}
if (found == true){
$("#msj").html("User already exists!");
}
else if(found == false){
Client["fullname"] = $("#fullname").val();
Client["username"] = user;
Client["email"] = $("#email").val();
Client["type"] = "client";
Client["password"] = $("#password").val();
clientlist[clientlist.length] = Client;
$("#msj").html("New client has been created");
}
}
Several problems with your for loop.
for (var i = 0; i < clientlist.length; i++) {
if (clientlist[i] == user) {
found = true;
}else{
found = false;
}
So what are we working with? clientlist is array so clientlist[i] is an element of that array...which happens to be an object.
user value is a string so there is no way to equate a string to object in the if.
Correction there would be to inspect the correct property value in object:
if (clientlist[i].username == user) {
Next problem is that the loop keeps going even if a match is found. As loop continues found will be updated for each iteration. Thus found will only be set based on the very last object in array regardless if a match was already determined.
To correct this could put that for loop in a function so it breaks the loop by returning true if match is found. Alternative would be use other array methods like Array.prototype.some() which returns a boolean based on conditional in callback. Or use break if a match is found to prevent loop continuing.
break will be simplest to plugin to the code so final would be
for (var i = 0; i < clientlist.length; i++) {
if (clientlist[i].username == user) {
found = true;
break;// quit loop since we found a match
}else{
found = false;
}
You need to change this
for (var i = 0; i < clientlist.length; i++) {
if (clientlist[i] == user) {
found = true;
}else{
found = false;
}
}
to
var found = false;
for (var i = 0; i < clientlist.length; i++) {
if (clientlist[i].username == user) {
found = true;
break;
}
}
You can use Array#some for this: It lets you run a callback against each entry in an array and determine if it matches a condition. some stops and returns true the first time you return a truthy value from the callback, or returns false if no calls to the callback return a truthy value.
So:
if (clientlist.some(function(entry) { return entry.username === user; })) {
$("#msj").html("User already exists");
} else {
// ...add the user...
}
That's more concise with ES2015+ arrow functions:
if (clientlist.some(entry => entry.username === user)) {
$("#msj").html("User already exists");
} else {
// ...add the user...
}
Also note that you don't want to reuse the same Client object each time, because on the next add, you'll just change the existing object's properties. Instead, create a new object each time:
clientlist.push({
username: user,
fullname: $("#fullname").val(),
email: $("#email").val(),
type: "client",
password: $("#password").val()
});
var clientlist = [{"username":"John","fullname":"John Doe",
"email":"john.doe#hotmail.com","type":"client","password":"jdoe2"}];
function NewClient() {
var user = $("#username").val();
if (clientlist.some(function(entry) { return entry.username === user; })) {
$("#msj").html("User already exists");
} else {
clientlist.push({
username: user,
fullname: $("#fullname").val(),
email: $("#email").val(),
type: "client",
password: $("#password").val()
});
$("#username, #fullname, #email, #password").val("");
$("#msj").html("New client has been created");
}
}
$("#btn").on("click", NewClient);
<div>
<label>
Username: <input type="text" id="username">
</label>
</div>
<div>
<label>
Fullname: <input type="text" id="fullname">
</label>
</div>
<div>
<label>
Email: <input type="text" id="email">
</label>
</div>
<div>
<label>
Password: <input type="password" id="password">
</label>
</div>
<div><input type="button" id="btn" value="Add"></div>
<div id="msj"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>