When to use return in Sequelize promises? - javascript

I am new to Sequelize and Promises which can be slightly a bit confusing for someone who is not very familiar with them and the javaScript language. Anyway, I have noticed that in some implementation of promises, the "return" is used. In other implementations it is not.
For example:
//FILL JOIN TABLE FROM EXISTING DATA
Blog.find({where: {id: '1'}}) .then(blog => {
return Tag.find({where: {id: '1'}}).then(tag => {
return blog.hasTag(tag).
then(result => {
// result would be false BECAUSE the blog.addTag is still not used yet
console.log("3 RESULT IS"+ result);
return blog.addTag(tag).
then(() => {
return blog.hasTag(tag).
then(result => {
// result would be true
console.log("4 RESULT IS"+ result);
})
})
})
})
})
And here: They are not used.
const tags = body.tags.map(tag => Tag.findOrCreate({ where: { name: tag }, defaults: { name: tag }})
.spread((tag, created) => tag))
User.findById(body.userId) //We will check if the user who wants to create the blog actually exists
.then(() => Blog.create(body))
.then(blog => Promise.all(tags).then(storedTags => blog.addTags(storedTags)).then(() => blog/*blog now is associated with stored tags*/)) //Associate the tags to the blog
.then(blog => Blog.findOne({ where: {id: blog.id}, include: [User, Tag]})) // We will find the blog we have just created and we will include the corresponding user and tags
.then(blogWithAssociations => res.json(blogWithAssociations)) // we will show it
.catch(err => res.status(400).json({ err: `User with id = [${body.userId}] doesn\'t exist.`}))
};
Can someone please explain to me the use of "return"? It is obviously not necessary since the second code works? So when do I have to use it?
Thank you!!

Technically, you asked about arrow function.
const dummyData = { foo: "lorem" };
const af1 = () => dummyData;
const af2 = () => {
dummyData.foo = "bar";
return dummyData;
};
const af3 = () => { foo: "bar" };
const af4 = () => ({
foo: "bar"
});
console.log(af1());
console.log(af2());
console.log(af3()); // Be aware if you wanna return something's started with bracket
console.log(af4());
As you see, we use return statement in af1 because we have to write another "logic" before return a value. If you don't do that, you can avoid using return statement (it could improve your code simplicity and readable).

Related

Using fetch and randomuser.me, how do I return multiple results?

I'm trying to use randomuser.me and I have the fetch request set up properly. I'm returning a single user. However, I want to return 5 comma separated users.
According to randomuser.me's documentation, I only need to append the fetch URI with ?results=5 (or any number I choose) and the multiple users are returned.
I've done this in the snippet below, but I'm still only returning a single user.
How do I return a comma separated result of 5 users?
window.onload = () => {
randomUserGenerator();
};
const randomUserGenerator = () => {
fetch("https://randomuser.me/api/?results=5")
.then((res) => {
return res.json();
})
.then((data) => {
showRandomUserData(data);
});
};
showRandomUserData = (randomUser) => {
document.getElementById("name").innerText =
`${randomUser.results[0].name.first} ${randomUser.results[0].name.last}`;
};
<h3><u>Users:</u> <span id="name"></span></h3>
using results[0] ... you're only USING the first user
Something like this may help you along
window.onload = () => {
randomUserGenerator();
};
const randomUserGenerator = () => {
fetch("https://randomuser.me/api/?results=5")
.then((res) => {
return res.json();
})
.then((data) => {
showRandomUserData(data);
});
};
showRandomUserData = (randomUser) => {
// combine all users
const users = randomUser.results.map(({name: { first, last}}) => `${first} ${last}`).join(', ');
// show them
document.getElementById("name").innerText = users;
};
<h3><u>Users:</u> <span id="name"></span></h3>

Argument of type 'void' is not assignable to parameter of type 'SetStateAction<never[]>'.ts(2345)

I want to implement a code to retrieve data from firestore collection
I use typescript as a programming language. But found an error while following the existing example, while the example uses javascript
the error occured at setBookmark(querySnapshot.forEach((doc) => {
React.useEffect(() => {
const getBookmark = async () => {
try {
const querySnapshot = await getDocs(collection(db, "bookmark"));
setBookmark(querySnapshot.forEach((doc) => {
id: doc.id,
data: doc.data()
// console.log(`${doc.id} => ${doc.data()}`);
}));
} catch (e) {
console.error("Error getting document: ", e);
}
};
getBookmark();
}, []);
forEach returns void hence the error. I think you want to use .map instead. Your current would always set setBookmark(null). I would write the code for you but its not clear what goes into bookmark.
map will return a new list based on the old list while forEach is to just iterate and not returning anything.
As I remember, you can't use map with querySnapshot, but you can create an array from it.
const myArray = [];
querySnapshot.forEach((doc) => {
myArray.push({
id: doc.id,
data: doc.data()
})
setBookmark(myArray)

How to define if #mentioned is subscriber? TMI.js

Trying to make little bot for my friend's twitch and want to make it define if "#mentioned" is a sub.
I decided to test if it define mods first but it always says "2"
client.on("chat", function (channel, user, message, self) {
if (message.toLowerCase().startsWith("!love")) {
var loved = message.split(' ')[1];
if (loved.mod || loved['user-type'] === 'mod'){
client.action(channel, "1 ");  //says sth
      }
else {
client.action(channel, "2 ");//says sth different
      }
}
user.mod
Is only available for user objects that are returned by the message handler. If you want to check if a mentioned user is a mod you have to request the chat list
function getAllChatters(channel, _attempts) {
return rp({
uri: `https://tmi.twitch.tv/group/user/${channel.replace('#','')}/chatters`,
json: true
})
.then(data => {
return Object.entries(data.chatters)
.reduce((p, [ type, list ]) => p.concat(list.map(name => {
return {name, type};
})), []);
})
.catch(err => {
if(_attempts < 3) {
return getChatters(channel, _attempts + 1);
}
throw err;
})
}
Then filter it for only mods
function getModsOnline(channel) {
return getAllChatters(channel)
.then(data => {
var mods = data.filter(chatter => chatter.type == 'moderators' || chatter.type == 'broadcaster').map(chatter => chatter.name);
return mods;
})
}
And then see if the user is in the list
function isModOnline(channel, username) {
// This will only return true if the mod is online in chat aka in the chat list
return getMods(channel)
.then(mods => {
return mods.includes(username);
})
}
Keep in mind that
This is for getting mods, not subscribers
It will only work for mods that are currently in chat, that list tends to update rather slowly
You need to work with promises here so
const rp = require('request-promise');
and to use the value
```
isModOnline(channel, username)
.then(value => {
// Code to work with the value here
console.log(`User is mod: ${value}`);
})

RXJS + Axios stagger network requests

I'm working with an API that has very strict rate limits and I need to send a number of requests to the same endpoint from names in an array. I set up a simple demo project and I tried this (and may variants of):
const pokemon = ['ditto', 'bulbasaur', 'charizard', 'pikachu'];
const obs = pokemon.map((pk, index) => {
return from(axios.get(`https://pokeapi.co/api/v2/pokemon/${pk}`)).pipe(delay(1000),map(res => {
return {id: res.data.id, name: res.data.name, height: res.data.height};
}));
});
concat(obs).subscribe(data => {
console.log(data);
});
but the Axios.get()'s all fire off when they are created and the concat().subscribe() just logs 4 observables. If I subscribe to the from().pipe() then after a second all 4 logout at once but then I'm subscribing in a subscribe which is poor.
The solution I settled on feels so cumbersome I have to believe there is a better way:
const axios = require('axios');
const { forkJoin, from } = require('rxjs');
const { map } = require('rxjs/operators');
const pokemon = ['ditto', 'bulbasaur', 'charizard', 'pikachu'];
const obs = pokemon.map((pk, index) => {
return from(new Promise(resolve => setTimeout(async () => {
const prom = await axios.get(`https://pokeapi.co/api/v2/pokemon/${pk}`);
resolve(prom);
}, index*1000))).pipe(map(res => {
console.log('fetched: ', pk);
return {id: res.data.id, name: res.data.name, height: res.data.height};
}))
})
forkJoin(obs).subscribe(data => {
console.log(data);
});
This delays the creation of the axios.get(), if I run with node --require debugging-aid/network rxjs_axios_delay.js I can see the delayed network requests and the real API I am hitting is happy, but this feels complicated and not very "RXy".
Anyone got anything better?
but the Axios.get()'s all fire off when they are created
this highlights a very interesting trait of Promises: they are eager. I think the defer operator can come in handy:
const pokemon = ['ditto', 'bulbasaur', 'charizard', 'pikachu'];
const obs = pokemon.map((pk, index) => {
return defer(() => axios.get(`https://pokeapi.co/api/v2/pokemon/${pk}`)).pipe(delay(1000),map(res => {
return {id: res.data.id, name: res.data.name, height: res.data.height};
}));
});
concat(...obs).subscribe(data => {
console.log(data);
});
StackBlitz demo.
The cool thing about defer is that it evaluates the given expression(i.e invokes the callback function) when it is being subscribed to.
This means you could also do things like these:
let dep$ = of('A');
const src$ = defer(() => dep$);
if (someCondition) {
dep$ = of('B')
}
// if `someCondition` is true, `dep$` will be `of('B')`
src$.pipe(...).subscribe()

using async methods inside of array.map() in javascript

I want to go through an array of elements and then for each element check if a theme exists with the "findOne()" function and if not create a new theme and save it and if that theme exists just apply some changes and then save and i want it to only continue after the theme is saved but .
internalRoutes.post('/add_questions', (req, res) => {
let elements = req.body
var count = 0;
elements.map((element) => {
let q = new Question({ category: element.category, body: element.body, level: element.level })
q.save().then(question => {
Theme.findOne({ name: element.theme }).then(theme => {
if (!theme) {
let new_theme = new Theme({ name: element.theme, level: element.level, questions: [], first_question: null })
new_theme.questions.push(question);
new_theme.first_question = question._id;
new_theme.save().then(t => {
console.log('new theeeeemmmmmmeeeeee')
})
}
else {
theme.questions.push(question);
theme.save().then(t => {
console.log('yeeeerrrrrrrrrrrrrecognized');
})
}
})
.catch(err => {
res.status(400).json("couldn't locate theme")
})
}).catch(err => {
res.status(400).json("couldn't save question")
})
count++;
})
if (count === elements.length) {
res.status(200).json({ message: "questions added successfully" })
}
else res.status(500).json('error')
})
here's my current code , i tried many ways such as async await functions or try catch blocks but never seem to solve this does anyone know where the issue could be ?
You probably want some sort of Promise.all implementation, so you know all of the promises you fired did return.
Your example code is fairly complex, so if you could simplify it I would be able to give you a more specific approach for your case.
const promisedElements = Promise.all(elements.map(async () => { ... })).then(...)

Categories