How to avoid writing same code for remoteMethods by calling remoteHooks in loopback 3?
I'm working on loopback 3. and I've defined remote hook methods like beforeRemote and afterRemote('find'). by hitting API links these hooks works fine, but when I use models and their methods inside other model API, those remote hooks doesn't work. Is there any way I can call any remote function of that model and that function also call it's specified beforeRemote and afterRemote hooks can help in avoid code redundancy and clean code.
models defined by loopback itself like User model does all operation hooks, but user defined isn't working like that.
See also questions close to this topic
-
Aws Lambda slow down after few request
I use Amazon Lamda with node12. I run htmlparser2 in my code. When I deploy application, htmlparser2's execution time is around 160ms. But after a while function execution time increases to 5000ms. Do you have any idea? In addition same situation in Google Cloud Functions.
index.js
const crawl = require('./crawl.js'); exports.helloWorld = async (req, res) => { const url = req.query.url; const result = await crawl(url); res.status(200).type('application/json').send(result); };
crawl.js
const bookRecipe = require('./recipes/book'); const quotesRecipe = require('./recipes/quotes'); module.exports = async (url) => { console.log('url', url); console.time('books'); const result = await bookRecipe(url); console.timeEnd('books'); console.time('quotes'); const quotes = await quotesRecipe(result.quotesLink); console.timeEnd('quotes'); result.quotes = quotes; return result; }
recipes/book.js
module.exports = async (url) => { const random = Math.floor(Math.random() * agents.length); const agent = agents[random]; console.time("books::fetch") const result = await fetch(url, { headers: agent }); console.timeEnd("books::fetch"); const text = await result.text(); console.time('books::parser'); const dom = htmlparser2.parseDocument(text); console.log('books::length', text.length); console.timeEnd('books::parser'); console.time('books::cheerio'); const $ = cheerio.load(dom); console.timeEnd('books::cheerio'); ... }
Everything is almost same in logs. But htmlparser2's execution is too long in second logs.
Logs:
Normal:
2021-01-26T05:43:28.976+03:00 2021-01-26T02:43:28.976Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO books::fetch: 134.696ms 2021-01-26T05:43:29.317+03:00 2021-01-26T02:43:29.317Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO books::length 520143 2021-01-26T05:43:29.317+03:00 2021-01-26T02:43:29.317Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO books::parser: 297.435ms 2021-01-26T05:43:29.317+03:00 2021-01-26T02:43:29.317Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO books::cheerio: 0.097ms 2021-01-26T05:43:29.360+03:00 2021-01-26T02:43:29.360Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO books: 518.615ms 2021-01-26T05:43:30.152+03:00 2021-01-26T02:43:30.152Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO quotes::fetch: 792.172ms 2021-01-26T05:43:30.218+03:00 2021-01-26T02:43:30.217Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO quotes::length 312774 2021-01-26T05:43:30.218+03:00 2021-01-26T02:43:30.217Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO quotes::parser: 59.300ms 2021-01-26T05:43:30.218+03:00 2021-01-26T02:43:30.218Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO quotes::cheerio: 0.081ms 2021-01-26T05:43:30.520+03:00 2021-01-26T02:43:30.520Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO quotes: 1159.586ms 2021-01-26T02:43:30.520Z 5e3c40c1-36ec-4e94-9230-cbd9d524f984 INFO quotes: 1159.586ms
Abnormal:
2021-01-26T05:44:48.379+03:00 2021-01-26T02:44:48.379Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO books::fetch: 181.431ms 2021-01-26T05:45:01.737+03:00 2021-01-26T02:45:01.720Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO books::length 518608 2021-01-26T05:45:01.737+03:00 2021-01-26T02:45:01.737Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO books::parser: 13316.728ms 2021-01-26T05:45:01.737+03:00 2021-01-26T02:45:01.737Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO books::cheerio: 0.159ms 2021-01-26T05:45:01.897+03:00 2021-01-26T02:45:01.897Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO books: 13699.625ms 2021-01-26T05:45:02.668+03:00 2021-01-26T02:45:02.667Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO quotes::fetch: 770.189ms 2021-01-26T05:45:09.798+03:00 2021-01-26T02:45:09.797Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO quotes::length 313700 2021-01-26T05:45:09.798+03:00 2021-01-26T02:45:09.798Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO quotes::parser: 7117.983ms 2021-01-26T05:45:09.798+03:00 2021-01-26T02:45:09.798Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO quotes::cheerio: 0.123ms 2021-01-26T05:45:09.861+03:00 2021-01-26T02:45:09.861Z 7770ae19-a466-4149-83d2-0d99b9c35a7f INFO quotes: 7963.365ms
-
How to get the hashed password to pass into my database?
I am able to run a test in Postman, but for some reason I am not passing my hashed password into the DB correctly.
const express = require("express"); // const helmet = require("helmet"); const { User } = require("./db/models"); const bcrypt = require("bcryptjs"); var salt = bcrypt.genSaltSync(10); var hash = bcrypt.hashSync('bacon', 8); const port = 4000; const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: true, limit: "50mb" })); // app.use(helmet()); app.get("/", (req, res) => { res.send("Hello World!"); });
Here is where i suspect the issue is. I am passing the name, email, and password in. I am trying to figure out how to get the hash to pass into the DB as the password.
app.post("/register", async (req, res) => { const user = await User.create({name:req.body.name, email:req.body.email, password:req.body.password}); bcrypt.genSalt().then(salt => { bcrypt.hash("password", salt).then(hash =>{ console.log(hash); }); }) console.log(req.body.name) res.json(user); }); app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`); });
-
How can I use Sequelize One-to-Many with Nodejs Express and React properly?
I have a form, where I want to save a "Horgaszat" with "Sor", but "Sor" should contain a foreign key value, as "horgaszatId" in the MySQL database.
I couldn't find out, where should I do this in the code. I use Sequelize to create a database, and in the database, I can see, that the foreign keys are there, but they don't get the "horgaszatid", their value is just NULL.The related parts of the code: horgaszat.controller.js
const db = require("../models"); const Horgaszat = db.horgaszatok; const Sor = db.sorok; exports.create = (req, res) => { const horgaszat = { horgaszhely: req.body.horgaszhely, datum: req.body.datum, fo: req.body.fo }; const sor = { nev: req.body.nev, darab: req.body.darab, }; Horgaszat.create(horgaszat) .then(data => { res.send(data); }) .catch(err => { res.status(500).send({ message: err.message || "Some error occurred while creating the Horgaszat." }); }); Sor.create(sor) .then(data => { res.send(data); }) .catch(err => { res.status(500).send({ message: err.message || "Some error occurred while creating the Tutorial." }); }); };
index.js
db.horgaszatok.hasMany(db.sorok); db.sorok.belongsTo(db.horgaszatok, { foreignKey: "horgaszatId", as: "horgaszat" });
add-horgaszat.component.js
import React, { Component } from "react"; import HorgaszatDataService from "../services/horgaszat.service"; export default class AddHorgaszat extends Component { constructor(props) { super(props); this.onChangeHorgaszhely = this.onChangeHorgaszhely.bind(this); this.onChangeDatum = this.onChangeDatum.bind(this); this.onChangeFo = this.onChangeFo.bind(this); this.onChangeNev = this.onChangeNev.bind(this); this.onChangeDarab = this.onChangeDarab.bind(this); this.saveHorgaszat = this.saveHorgaszat.bind(this); this.newHorgaszat = this.newHorgaszat.bind(this); this.state = { id: null, horgaszhely: "", datum: "", fo: 0, nev: "", darab: 0, submitted: false }; } onChangeHorgaszhely(e) { this.setState({ horgaszhely: e.target.value }); } onChangeDatum(e) { this.setState({ datum: e.target.value }); } onChangeFo(e) { this.setState({ fo: e.target.value }); } onChangeNev(e) { this.setState({ nev: e.target.value }); } onChangeDarab(e) { this.setState({ darab: e.target.value }); } saveHorgaszat() { var data = { horgaszhely: this.state.horgaszhely, datum: this.state.datum, fo: this.state.fo, nev: this.state.nev, darab: this.state.darab, }; HorgaszatDataService.create(data) .then(response => { this.setState({ id: response.data.id, horgaszhely: response.data.horgaszhely, datum: response.data.datum, fo: response.data.fo, nev: response.data.nev, darab: response.data.darab, submitted: true }); console.log(response.data); }) .catch(e => { console.log(e); }); } newHorgaszat() { this.setState({ id: null, horgaszhely: "", datum: "", fo: 0, nev: "", darab: 0, submitted: false }); } render() { return ( <div className="submit-form"> {this.state.submitted ? ( <div> <h4>Sikeresen elmentetted!</h4> <button className="btn btn-success" onClick={this.newHorgaszat}> Felvesz </button> </div> ) : ( <div> <div className="form-group"> <label htmlFor="horgaszhely">Horgászhely</label> <input type="text" className="form-control" id="horgaszhely" required value={this.state.horgaszhely} onChange={this.onChangeHorgaszhely} name="horgaszhely" /> </div> <div className="form-group"> <label htmlFor="datum">Dátum</label> <input type="date" className="form-control" id="datum" required value={this.state.datum} onChange={this.onChangeDatum} name="datum" /> </div> <div className="form-group"> <label htmlFor="fo">Fő</label> <input type="number" className="form-control" id="fo" required value={this.state.fo} onChange={this.onChangeFo} name="fo" /> </div> <div className="form-group"> <label htmlFor="nev">Sör neve</label> <input type="text" className="form-control" id="nev" required value={this.state.nev} onChange={this.onChangeNev} name="nev" /> </div> <div className="form-group"> <label htmlFor="darab">Sör száma</label> <input type="number" className="form-control" id="darab" required value={this.state.darab} onChange={this.onChangeDarab} name="darab" /> </div> <button onClick={this.saveHorgaszat} className="btn btn-success"> Mentés! </button> </div> )} </div> ); } }
I used these tutorials:
https://bezkoder.com/node-js-express-sequelize-mysql/
https://bezkoder.com/sequelize-associate-one-to-many/ -
O365 - Security & Compliance Center - How to generate an Alert for API testing
I wanted to know what is the quickest possible way to generate an alert in the Alert > view Alerts section for API testing
-
Fetch API data with chain of .then methods, but data is not passing through to the next .then
I'm making three http get requests to create an array of unique objects. I'm sharing an example with a random API, not quite the same, but it's captures the essence: Codepen Example The main bug lies in the last 2 then methods of the getData function.
In the getData function, I pass the sorted list of users to the getUniqueGender function, where it fetches more data objects and pushes the first "unique" user by gender to the uniqueUsers array. The getUniqueGender function returns the uniqueUsers array but it doesn't seem to be doing that, why? I've added a console.log in line 28 (Codepen Example) to check if it's ready pushing the user into the array and it's doing so but it's returning an empty array to the next then method. In my actual code, the array passed to the next then method can be printed to the console but I cannot do any computation from that point on, it prints the array.length as 0 to the console.
Please help me debug this. I've been trying to debug this for days... :(
let uniqueUsers = []; let finalUsers = []; function sortUsers(arr) { /*dummy function to show the synchronous step*/ return arr; } function getUniqueGender(arr) { if (arr.length > 0) { for (let user of arr) { fetch('https://api.randomuser.me/?nat=US&results=${arr.length}') .then((res) => res.json()) .then((json) => json.results) .then((results) => { if (results.length > 0) { for (let res of results) { if (!uniqueUsers.some((uniqueUser) => uniqueUser.gender === res.gender)) { //console.log('users gender is unique so its added'); //console.log(res.gender); let editedUser = { gender: res.gender , email: res.email , }; uniqueUsers.push(editedUser); console.log(uniqueUsers) } else { //console.log('users gender is NOT unique so its NOT added'); //console.log(res.gender); } } } }); } //console.log(uniqueUsers) //this work in my actual code... return uniqueUsers; } else { return uniqueUsers; } } function appendInfo(arr) { console.log(arr) //this works in my actual code... for (let uniqueUser of arr) { fetch('https://api.randomuser.me/?nat=US&results=1') .then((res) => res.json()) .then((json) => json.results) .then((randomUser) => { let editedUniqueUser = { gender: uniqueUser.gender , email: uniqueUser.email , nat: randomUser.nat }; finalUsers.push(editedUniqueUser); }); } console.log(finalUsers) return finalUsers; } function getData() { fetch('https://api.randomuser.me/?nat=US&results=5') .then((res) => res.json()) .then((json) => json.results) .then((users) => sortUsers(users)) .then((sortedUsers) => getUniqueGender(sortedUsers)) .then((uniqueUsers) => appendInfo(uniqueUsers)) .then((result) => console.log(result)) //why this doesn't work?? .catch(console.log); } getData()
-
Programmatically add a POST method to AWS API gateway
I am trying to programmatically create a POST method from an AWS API gateway which invokes a lambda function. However I don't know how to do this. This is what I have tried:
response = client.create_rest_api( name=api_name, endpointConfiguration={ 'types': [ 'REGIONAL', ], }, )
This creates the API.
response = client.put_method( restApiId=api_id, resourceId=func_arn, httpMethod='POST', authorizationType='NONE', )
I am putting the API string ID (not the name) and am passing the lambda ARN. However, I am getting the error:
botocore.errorfactory.NotFoundException: An error occurred (NotFoundException) when calling the CreateResource operation: Invalid Resource identifier specified
I don't know what I am doing wrong. Any help in getting the API POST method to invoke the lambda would be appreciated.
-
In Loopback 4, how to avoid update of few fields
In loopback framework, is there a way to avoid updates for few fields
Below code allows updates for all fields that is passed in the API request body.
async updateById( @param.path.number('id') id: number, @requestBody({ content: { 'application/json': { schema: getModelSchemaRef(Todo, {partial: true}), }, }, }) todo: Todo, ): Promise<void> { await this.todoRepository.updateById(id, todo); }
-
NodeJS(Loopback): loopback-connector-rest with multipart/form-data (FormData)
I am trying to call a 3rd party API with loopback-connector-rest POST request (multipart/form-data), while I am creating a instance of form-data in the request body, and try to access it, It throws error from request package. How can I use formData. On passing formData inside the connector-template, it don't show. Where should I use form-data, in body or form?
Unhandled rejection TypeError: Method get TypedArray.prototype.length called on incompatible receiver [object Object]
NOTE: Reading a file from the container as buffer and adding to form data.
-
Can we set default value for limit in loopback framework find API?
I have a API
http://localhost:3000/todos?filter[where][type]=read&filter[limit]=2
Want to specify default limit as 20 and also want to validate limit value to be less than or equal to 20.
Wanted to check if we can have validation and also default value for limit filter?