Javascript - JSON file returning [object Object] - javascript

For some reason when I try and call my command it returns [object Object],[object, Object]
fs.readFile(path.join(__dirname, "../moderation") + "/modlogs.json", "utf-8", function(err, data) { // read the JSON file
if (err) throw err; // throw error if applicable
var arrayOfObjects = JSON.parse(data); // parse the data
for (let i = 0; i < arrayOfObjects.warns.length; i++) { // loop through all keys in warns file
if (arrayOfObjects.warns[i].user_id === user.id) { // check if the user has already been warned
message.reply("User already warned. Kicking user."); // display kick
//message.guild.member(user).kick(); // kicks member
indexOfUser = arrayOfObjects.warns.findIndex(x => x.user_id == user.id); // find the index of the users object
//message.channel.sendMessage(indexOfUser);
message.channel.sendMessage("Before splicing" + arrayOfObjects.warns);
//arrayOfObjects.warns.splice(indexOfUser, 1); // remove the user from warns array
message.channel.sendMessage("After splicing" + arrayOfObjects.warns);
return;
};
};
The line //arrayOfObjects.warns.splice(indexOfUser, 1); // remove the user from warns array is supposed to delete that object from the warns array in my JSON file. However it doesn't, the console.logs were just to see what was getting outputed, and it seems like the values aren't getting through.

I think the problem is that you are using findIndex() instead indexOf() when you try to find the index.
Array.prototype.indexOf() expects a value as first parameter. This makes it a good choice to find the index in arrays of primitive types.
Array.prototype.findIndex() expects a callback as first parameter. Use this if you need the index in arrays with non-primitive types (e.g. objects) or your find condition is more complex than just a value.
See the links for examples of both cases.
info from this post
Edit:
I bring you some usefull code.
With indexOf()
if (arrayOfObjects.warns.indexOf(user_id) > -1) { // check if the user has already been warned
message.reply("User already warned. Kicking user."); // display kick
//message.guild.member(user).kick(); // kicks member
indexOfUser = arrayOfObjects.warns.indexOf(user_id);
//message.channel.sendMessage(indexOfUser);
message.channel.sendMessage("Before splicing" + arrayOfObjects.warns);
//arrayOfObjects.warns.splice(indexOfUser, 1); // remove the user from warns array
message.channel.sendMessage("After splicing" + arrayOfObjects.warns);
return;
};
Aclaration: indexOf(value) returns -1 if it can't find the item in the Array. Otherwise it returns the index where item is located. So you don't need to iterate in the array.
with findIndex()
When using findIndex() you don't define the value you want to find in the array. You define the function that will be executed every iteration.
You could do something like:
function iswarned (elem) {
return elem.user_id == user_id;
}
if (arrayOfObjects.warns.findIndex(iswarned) > -1) {
indexOfUser = arrayOfObjects.warns.findIndex(iswarned);
}
Aclaration: findIndex() returns the first index for what callback function returns a truthy value or -1 If the callback never returns a truthy value or array.length is 0.

Related

Array of objects returning null

I have this code that formats an array of objects, which is set out how I want it. However, when I go to return the output something strange happens. If I were to just return alert_cache, it returns null. But If I were return it like alert_cache.workflow_steps it returns the data needed.
Does anyone have any idea how to get around this?
if (alert_cache.length == 0) {
alert_cache.workflow_steps = {}
alert_cache.workflow_steps[keys.workflow_step] = { "errors": [], "last_error": {}};
let alr = alert_cache.workflow_steps[keys.workflow_step];
alr.errors.push(now)
alr.last_error = {message: keys.message, url:alert.step_log_url}
}
return alert_cache;
You're using alert_cache like an array and like an object. You're checking length (as if it were an array):
if (alert_cache.length == 0) {
but you're also assigning to a non-element property:
alert_cache.workflow_steps = {}
Note that doing that will not change length.
You haven't shown how you create alert_cache to start with, but if it's an array, and if you're then using it with something that only looks at its array entries and not at its other properties (for instance, JSON.stringify), it will be empty (not null).

Object and array processing code not working

I'm trying to create a function called maybeNoises to test if an array has noises or not and then to print them to the console.
The prompt is as follow:
Function should take an object, if this object has a noises array return them as a string separated by a space, if there are no noises return 'there are no noises' (2, 1, 3)
This is my code:
function maybeNoises(object) {
if (object.noises) {
return object.noises.join(" ");
} else if (object["noises"].isArray(undefined)) {
console.log("THIS TEST IS STUPID AND PISSING ME OFF");
} else(object["noises"].isArray(null));
return 'there are no noises';
}
This is what it is testing:
QUnit.test("maybeNoises() : Should take an object, if this object has a noises array return them as a string separated by a space, if there are no noises return 'there are no noises'",
function(assert) {
assert.equal(maybeNoises({
noises: ["bark", "woof", "squeak", "growl"]
}), "bark woof squeak growl");
assert.equal(maybeNoises({
noises: []
}), "there are no noises");
assert.equal(maybeNoises({}), "there are no noises");
});
What am I doing wrong?
The issues with your code are
else(object["noises"].isArray(null)) isn't valid syntax
if (object.noises) return object.noises.join(" "); - your first test assumes that object has a property named noises, and that this noises object has a property called join which is a function ... that's a lot to assume without testing!!! ... what if noises is true for example, true doesn't have a join property! What if object is null/undefined? It doesn't even have a property called noises!
object["noises"].isArray(undefined) an array doesn't have a isArray function, only Array (literally, Array, not "an Array") has that function, and the argument to it should be the object you want to test
So, here's all you need to do
function maybeNoises(object) {
// we know nothing about object yet, so lets not assume
if (object && object.noises) { // check that object and object.noises are "something"
// here, we know that object.noises is "something"
if (Array.isArray(object.noises)) { // check that object.noises is an Array
// here we know that object.noises is an array, so, it has a length
if (object.noises.length > 0) { // check length is > 0
return object.noises.join(' ');
}
}
}
return 'there are no noises'; // didn't pass the above tests, so return this string
}
I edited my answer to summarize all the problems:
1.) Check if there is a noises array.
You wanna do Array.isArray(object.noises) or if you are in the unlikely event of this not working in your javascript implementation you can check for other alternatives here: Check if object is array?
2.) Check if the array has elements:
object.noises.length can be used to see if the array has any entries.
3.) Return the noises as array
You figured that out already correctly.

Unable to add data to an array taken out from a cookie

Am not able to add data to an array taken out from a cookie .
var x1 =[];
if($cookies.get(uid )== undefined)
{
var arr =[];
arr.push($scope.stock);
$cookies.put("arr",JSON.stringify(arr));
$cookies.put("uid","xxx");
console.log("==uid not found in cookie in angular --- cookies.uid"+ $cookies.get("arr"));
}
else
{
console.log("inside else"+JSON.stringify($cookies.getObject("arr"))); // gives output ["bse:yesbank"]
x1= JSON.stringify($cookies.getObject("arr"));
----> console.log(x1 instanceof Array); // returns false
----> x1.push($scope.stock);
}
it gives
x1.push is not a function
Moreover, it's says the JSON.stringify($cookies.getObject("arr")) is not an array but the value of above expression is ["bse:yesbank"] which is nothing but an array. please correct me where I am getting wrong .
That is because you use JSON.stringify, wich turns the array into a string looking like the array.
Try to get the value without stringify:
x1= JSON.stringify(["test"]);
console.log(x1 instanceof Array); // returns false
console.log(JSON.parse(x1) instanceof Array); // returns true

What is the meaning of check for this.length into a function?

I'm following an online course about Javascript Functional Programming
at the Exercise 16 it show you how reduce is actually implemented, in order to help you understand how to use it, but into this implementation there is something i don't actually get, i'll show the code:
Array.prototype.reduce = function(combiner, initialValue) {
var counter, accumulatedValue;
// If the array is empty, do nothing
if (this.length === 0) {
return this;
}
else {
// If the user didn't pass an initial value, use the first item.
if (arguments.length === 1) {
counter = 1;
accumulatedValue = this[0];
}
else if (arguments.length >= 2) {
counter = 0;
accumulatedValue = initialValue;
}
else {
throw "Invalid arguments.";
}
// Loop through the array, feeding the current value and the result of
// the previous computation back into the combiner function until
// we've exhausted the entire array and are left with only one value.
while(counter < this.length) {
accumulatedValue = combiner(accumulatedValue, this[counter])
counter++;
}
return [accumulatedValue];
}
};
I don't understand the first if statement, when it check for this.length what this actually mean?
Take note this is different from the reduce in ES5, which returns an value instead of an Array, this is used just as a sample for the learning purpose.
Array.prototype.reduce = function(...
is saying, "create a function on the prototype of Array" - this means that the new reduce function will be callable on all arrays, eg:
[1, 2, 3].reduce(...
This means you can also call it on empty arrays, eg:
[].reduce(...
Building on the comment:
If the array is empty, do nothing
You're working on an array, and when the function is called, this is set to the array that reduce was called on. This implementation of reduce assumes that if that array is empty (ie this.length === 0), you can't logically reduce it any further - there's nothing to reduce, so you can return the same empty array.
As pointed out by #Alnitak in the comments, this implementation of reduce is flawed as compared to the specification. A different implementation is available on the MDN for polyfilling older browsers.

How to add value to an object inside function?

I loop through an array and depending on the conditions I want to add different values to an object.
The first console.log() outputs the value. The second one doesn't output anything. Why? And what can I do about it? The desired outcome is that if any of the keywords is inside nicecontact.fulladress, the string should be splitted and added using that keyword. if none of the values are, I want fulladress=adress
var niceContact= {}
niceContact.fulladress = $.trim(contact[2])
//cut out lgh if it's in there.
var keywords = ["Lgh", "lgh"]
niceContact.adress = keywords.some(function(keyword){
if (niceContact.fulladress.indexOf(keyword) != -1){
adressarray = niceContact.fulladress.split(keyword)
niceContact.adress = adressarray[0]
console.log(niceContact.adress)
return adress;
}else{
console.log('false')
niceContact.adress = niceContact.fulladress
}
})
console.log(niceContact.adress)
Thats not what Array.some is for. Shouldnt be returning a value from it:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
some executes the callback function once for each element present in the array until it finds one where callback returns a true value. If such an element is found, some immediately returns true. Otherwise, some returns false. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.
var niceContact= {}
var hadHit = false
niceContact.fulladress = $.trim(contact[2])
//cut out lgh if it's in there.
var keywords = ["Lgh", "lgh"]
niceContact.adress = niceContact.fulladress
keywords.forEach(function(keyword){
if (!hadHit && niceContact.adress.indexOf(keyword) != -1){
// do your checking for the keywords here
// and modify niceContact.adress if needed
// if you're looking to `break` out of the .forEach
// you can `return false;` instead (same as break) see http://stackoverflow.com/questions/6260756/how-to-stop-javascript-foreach
// or if you have a hit, just do `hadHit = true` after mod-ing the address
}
})
console.log(niceContact.adress)

Categories