function is returning undefined javascript - javascript

I wrote a function in javascript expression to check if the result is true or false but i am always getting undefined error
var array = [{
email: 'usman#gmail.com',
password: '123'
},
{
email: 'ali#gmail.com',
password: '123'
}
];
let main = function(email, password) {
return array.forEach((row) => {
if (row.email === email && row.password === password) {
return true
} else {
return false
}
});
};
var checkLogin = main('usman#gmail.com', '123');
console.log(checkLogin)
checkLogin always return undefined

It's because forEach does not return anything. You can use simple for-loop, like this:
var array = [
{email: 'usman#gmail.com', password: '123'},
{email: 'ali#gmail.com', password: '123'}
];
let main = function(email, password) {
for (var i = 0; i < array.length; i++) {
var row = array[i];
if (row.email === email && row.password === password) {
return true
}
}
return false;
};
var checkLogin = main('usman#gmail.com', '123');
console.log(checkLogin)
Also, take a look at some(), includes(), find() and findIndex()

The forEach array function doesn't return anything. If you touch looped array inside it then you are able to modify existing array without copying it.

there's a problem with foreach. it doesn't return anything
var array = [
{email: 'mike#gmail.com', password: '123'},
];
let main = function(email, password) {
for (var i = 0; i < array.length; i++) {
if (array[i].email === email && array[i].password === password) {
return true
}
};
return false
};
var checkLogin = main('mike#gmail.com', '123');
console.log(checkLogin) // returns true

there is something wrong with this logic:
return array.forEach((row) => {
if (row.email === email && row.password === password) {
return true
} else {
return false
}
});
without this logic it returns anything you want

You could take Array#some and return the result of the check.
var array = [{ email: 'ali#gmail.com', password: '123' }, { email: 'usman#gmail.com', password: '123' }];
let main = (email, password) =>
array.some(row => row.email === email && row.password === password);
var checkLogin = main('usman#gmail.com', '123');
console.log(checkLogin)

Related

Nodejs Execute after a recursive function is done

I have a controller that basically performs a recursive call to retrieve how categories and their deleted items, but a "category_item" has a property called "next_steps" which is an array of categories, so I need to retrieve those categories and their items as well.
So I made a recursive function, it works, but I need to run something else when it actually ends, how can I do that? here's my code:
const recoveryCategory = async (req, res) => {
try {
const categoryId = req.params.categoryId
const category = await nmCategorySvcV2.getByIdDeleted(categoryId)
if (category === null){
throw new Error("This category is not deleted.")
}
__recoveryRecursive(categoryId)
// run something after
res.json({ success: true, message: "Success." })
} catch (err){
res.json({ success: false, message: err.message })
}
}
const __recoveryRecursive = async (categoryId) => {
const category = await nmCategorySvcV2.getByIdDeleted(categoryId)
if (category === null){
return
}
await nmCategorySvcV2.update(categoryId, { deleted: false })
const categoryItens = await categoryItemSvcV2.getAllItensByCategory(categoryId)
for (let i = 0; i < categoryItens.length; i++) {
const categoryItem = categoryItens[i]
if (categoryItem.deleted == true) {
const item = await itemSvcV2.getByIdNoPopulate(categoryItem.item, categoryItem.page)
if (item.deleted == true) {
itemSvcV2.update(item._id, { deleted: false })
categoryItemSvcV2.updateItensProp(item._id, { deleted: false })
}
const itemPrice = await itemPriceSvcV2.getById(categoryItem.price)
if (itemPrice.deleted == true) {
itemPriceSvcV2.updateObject({ _id: itemPrice._id }, { deleted: false })
}
categoryItemSvcV2.update(categoryItem._id, { deleted: false })
if (categoryItem.next_steps.length > 0){
for (let j = 0; j < categoryItem.next_steps.length; j++){
const categryNextStep = categoryItem.next_steps[j].category
__recoveryRecursive(categryNextStep)
}
}
}
}
}
Just add await before the recursive call because it returns a promise wich must be handled .

JavaScript ignoring adding object to array

function setUsersDefinitions(data, userID){
let users = new Array();
return new Promise((resolve)=>{
data.forEach(el => {
if (el.id_adder === userID) {
getUserName(el.id_added).then(u => {
users.push({
username: u,
locked: el.locked !== null,
canUnlock: el.locked === userID,
id: el.id_added
})
}).catch(e=>{
console.log(e);
})
} else {
getUserName(el.id_adder).then(u=>{
users.push({
username: u,
locked: el.locked !== null,
canUnlock: el.locked === userID,
id: el.id_adder
})
}).catch(e=>{
console.log(e);
})
}
})
resolve(users);
})
}
The problem is that when i try doing a console.log of the item generated it works but when it call Array.push method, it ignore that command.
What am I doing wrong?
Thanks in advance.
All of this should be done with async/await, and not by wrapping the whole lot in a Promise - it will hugely simplify your code:
async function setUsersDefinitions(data, userID){
let users = new Array();
for(var i=0;i<data.length;i++){
var el = data[i];
var id = (el.id_adder === userID) ? el.id_added : el.id_adder;
var u = await getUserName(id);
users.push({
username: u,
locked: el.locked !== null,
canUnlock: el.locked === userID,
id: id
});
}
return users;
}
(Note: Error handling omitted for brevity)
You should then await this function wherever you call it (must itself be within an async function):
async function doWork(){
var users = await setUsersDefinitions(some_data, some_userID);
console.log(users);
}

Hapi.js user authentication with mongodb issue

For, an user verification now I hardcoded the username and password directly on my code. But I want this dynamically using database username and password. As, i'm new to hapi.js it seems quite difficult for me. This is my code :
app.js
const auth = require('hapi-auth-basic');
const hapi = require('hapi');
mongoose.connect('mongodb://localhost:27017/db', {
useNewUrlParser: true }, (err) => {
if (!err) { console.log('Succeeded.') }
else { console.log(`Error`)}
});
const StudentModel = mongoose.model('Student', {
username: String,
password: String
});
const user = {
name: 'jon',
password: '123'
};
const validate = async (request, username, password, h) => {
let isValid = username === user.name && password === user.password;
return {
isValid: isValid,
credentials: {
name: user.name
}
};
};
const init = async () => {
await server.register(auth);
server.auth.strategy('simple', 'basic', {validate});
server.auth.default('simple');
server.route({
method: 'GET',
path: '/',
handler: async (request, h) => {
return 'welcome';
}
});
}
I tried to do this by changing the validate as below :
const validate = async (request, username, password, h) => {
let isValid = username === request.payload.name && password === request.payload.password;
return {
isValid: isValid,
credentials: {
name: request.payload.name
}
};
};
but i got the type error "name" as it's natural. How can I modify this?
Here, fetch user and check in the validation method
const validate = async (request, username, password, h) => {
// fetch user here
const user = await StudentModel.findOne({username, password}).exec();
// user doesn't exist
if(!user) return {isValid: false}
// just make sure here user really exists
return {
isValid: true,
credentials: {
name: user.name
}
}
}

comparing user input arrays & objects

I need to compare user input with set usernames and passwords. For now this is what I came up with:
var sys = {
users: [
{user: 'user1', pass: 'qwerty'},
{user: 'Ragnar', pass: 'lothbrok'},
{user: 'guest', pass: 'guest'}
],
valid: function(){
var userInp = document.getElementById("userInp").value;
// var pwInp = document.getElementById("pwInp").value;
var check = false;
for (var i=0; i < sys.users.length; i++ ){
if (userInp == sys.users.user /*&& apwInp == 'sys.users{pass}'*/) {
alert ("logged in")
} else {
alert ("no match")
}
}
}
}
I need to do it in this specific way and I can't figure it out.
Just to have some clarity, have your username-password combination as a separate object and use the authentication in a different block of code.
//username-password objects
var sys = {
users: [
{user: 'user1', pass: 'qwerty'},
{user: 'Ragnar', pass: 'lothbrok'},
{user: 'guest', pass: 'guest'}
]}
//take your inputs and store them in a variable
var username = document.getElementById("userInp").value;
var password= document.getElementById("passInp").value;
var count = 0;
for(i = 0; i< sys.users.length; i++)
{
if(sys.users[i].user == username && sys.users[i].pass == password)
count++;
}
if(count>0)
alert("correct credentials");
else
alert("incorrect credentials");
You have pretty much in your code already, hope this clears out the rest.
Use Array::some
var sys = {
users: [
{
user: 'user1',
pass: 'qwerty'
},
{
user: 'Ragnar',
pass: 'lothbrok'
},
{
user: 'guest',
pass: 'guest'
}
],
valid: function () {
let username = "Ragnar";
let password = "lothbrok";
return sys.users.some(u => u.user === username && u.pass === password);
}
}
console.log(sys.valid())

How to check each object in array in ReactJS + Redux?

I have an object array of users, which each object has 'username' and 'password'.
There is then a login page, where once the user enters in a username and a password, I want to pass that into the reducer and compare them with each object in the 'users' array, and if an object that matches both, 'password' and 'username', is found, I want it return 'true'.
Following is the reducer:
const usersReducer = function(users = [], action){
switch (action.type){
case 'VERIFY_USER':
return users.map((user)=> {
if(user.username === action.username && user.password === action.password){
return true
} else{
return false
}
})
}
default:
return users
}
}
But it seems to return true all the time. Am I using map correct? If not, is there such a method where it'll go through each object in an array? Any insight or guidance would be appreciated. Thank you in advance!
EDIT**
Calling it from the following:
verifyLoginUser(){
event.preventDefault()
if(this.props.actions.verifyUser(this.props.loginUser.username, this.props.loginUser.password)){
console.log('LOGGED IN')
} else {
console.log('NOT LOGGED IN')
}
}
With the following reducer:
case 'VERIFY_USER':
let isVerified = false;
users.forEach((user)=> {
if(user.username === action.username && user.password === action.password){
isVerified = true;
return false;
}
});
return isVerified;
Use Array.some
return users.some(user => user.username === action.username && user.password === action.password);
Map function would return you an array. I suggest using a different native array function: 'find'. To check if user object exists in the array of users, you can do
function findUser(user) {
return (user.username === action.username && user.password === action.password);
}
var isUser = users.find(findUser) ? true : false;
return isUser;
use a boolean variable and forEach to accomplish what you want
case 'VERIFY_USER':
let isVerified = false;
users.forEach((user)=> {
if(user.username === action.username && user.password === action.password){
isVerified = true;
return false;
}
});
return isVerified;
to take this a step further lets say you wanted to iterate on this and return the correct user so that way you can populate a currentUser with it or something.
case 'VERIFY_USER':
let currentUser = null;
users.forEach((user)=> {
if(user.username === action.username && user.password === action.password){
currentUser = user;
return false;
}
});
return currentUser;
EDIT: to what we were talking about in the comments
lets say you make a request to login a user somewhere. and the function lives on your props
this.props.loginUser({my params here});
now your actual action.
loginUser = (data) => {
// whatever method you are using to make the request goes here.
someRequestMethod('/login/, data).then( (response) => {
if(response.status === 200){
dispatch(type: USER_LOGIN, payload: response.data); // whatever the user is that comes back from the response. I just put data for an example
}
})
}
now in your reducer
const populateState = (user) => {
return {
id: user.id,
username: user.username,
email: user.email,
isAuthenticated: Object.keys(user).length > 0
};
}
let defaultState = {id: null, username: '', email: '', isAuthenticated: false};
const loginReducer = (currentUser = defaultState) => {
switch (action.type){
case 'USER_LOGIN':
return Object.assign({}, currentUser, populateState(action.payload));
return currentUser;
}
finally, everywhere else you just look for the current user.
if(this.props.currentUser.isAuthenticated){
// do stuff
}

Categories