populate hooks with axios json response reactjs - javascript

I'm having hard time on thinking how will I populate hooks with API response(json)
see below codes
cosnt [loginResponse, setloginResponse] = useState({
Token: '',
UserID: '', //from user-id
UserName: '', //from user-userName
firstName: '', //from user-firstName
rcCode: '' //from attributes-rcCode
})
const login = async () => {
await axios.get('/API')
.then(response => {
console.log('response.data', response.data.resp)
});
}
here's the result of console.log(response.data.resp)
{
"data": {
"token": "abcd",
"user": {
"id": "123456",
"userName": "uname",
"firstName": "FNAME",
"lastName": "MNAME",
"email": "email#email.com",
"attributes": {
"favorites": ["FAV"],
"rcCode": ["123"]
},
"requiredActions": [],
"roles": ["ROLE"]
},
"modulePermissions": []
}
}
for console.log(response.data):
"resp": {
"data": {
"token": "abcd",
"user": {
"id": "123456",
"userName": "uname",
"firstName": "FNAME",
"lastName": "MNAME",
"email": "email#email.com",
"attributes": {
"favorites": ["FAV"],
"rcCode": ["123"]
},
"requiredActions": [],
"roles": ["ROLE"]
},
"modulePermissions": []
}
},
"success": true
I want to populate my hooks with those datas for me to utilize it on my page.
I got undefined if I tried to console.log(response.data.resp.data)
On console.log(response), I got:
Thank you.

Don't use async/await and .then() together. Use either of those.
const login = async () => {
const response = await axios.get('/API');
const parsedData = JSON.parse(response.data.resp);
const userData = parsedData.data;
setLoginResponse({
Token: userData.token,
UserID: userData.user.id,
UserName: userData.user.userName,
firstName: userData.user.firstName,
rcCode: userData.user.attributes.rcCode
});
}

In the .then
setLoginResponse({...loginResponse, Token: response.data.resp.data.token, UserId: response.data.resp.data.user.id, ...}
You can destructure your response object first and store values in variables to make the setLoginResponse more easy to read.
https://reactjs.org/docs/hooks-state.html

Related

how i can set all json code in Braces/{}?

i have a question, how can i set a json code in Braces/{} ?
all code in down explained what i need do
i want to do this for login system if i have any error i'm sorry for that
look like that
{
"test": "test",
"test1": "test1"
}
that my code
var usac = JSON.stringify({username: newusername, password: newpassword }, null, 2)
fs.appendFile('account.json', usac, fin)
function fin(err){
console.log("done")
}
that my json code
{
"username": "test",
"password": "test"
}{
"username": "test1",
"password": "test1"
}{
"username": "test2",
"password": "test2"
}{
"username": "test3",
"password": "test3"
}{
"username": "test4",
"password": "test"
}
i want code be right that
{
"user" :{
"username": "test",
"password": "test"
}
"user1" :{
"username": "test1",
"password": "test1"
}
"user2" :{
"username": "test2",
"password": "test2"
}
"user3" :{
"username": "test3",
"password": "test3"
}
"user4" :{
"username": "test4",
"password": "test4"
}
}
You are appending to a json file. But, the content is not json.
One quick solution is:
Create the file with {} as initial content.
Read the file
Parse the contents to JavaScript Object
Set new account object in the parsed object with username as key & account object as value.
Stringify the JavaScript Object
Overwrite the same file with the stringified data
const fs = require('fs');
class AccountsInterface {
constructor(filePath) {
this.filePath = filePath;
}
getAll(callback) {
fs.readFile(this.filePath, function onReadComplete(error, content) {
if(error) {
return callback(error);
}
const accountsMap = JSON.parse(content.toString());
callback(null, accountsMap);
});
}
addAccount(account, callback) {
const self = this;
self.getAll(function onAccountsLoaded(error, accountsMap) {
if(error) { return callback(error); }
accountsMap[account.username] = account;
const accountsMapString = JSON.stringify(accountsMap);
fs.writeFile(self.filePath, accountsMapString, function onWriteComplete(error) {
if(error) { return callback(error); }
callback();
});
});
}
// Async version
async getAllAsync() {
const content = await fs.promises.readFile(this.filePath);
const accountsMap = JSON.parse(content.toString());
return accountsMap;
}
async addAccountAsync(account) {
const accountsMap = await this.getAllAsync();
accountsMap[account.username] = account;
const accountsMapString = JSON.stringify(accountsMap);
await fs.promises.writeFile(this.filePath, accountsMapString);
}
}
// Ensure this file's contents are `{}` in the beginning
const accountsFilePath = './accounts.json';
const accountsInterface = new AccountsInterface(accountsFilePath);
const account = { username: 'test', password: 'test'};
accountsInterface.addAccount(account, onAccountAdded);
function onAccountAdded(error) {
if(error) { return console.log(error); }
// here, the accounts file will look like {"test": {"username": "test", "password": "test"}}
}
// Async version
const account = { username: 'test2', password: 'test2'};
await accountsInterface.addAccountAsync(account);
// here, the accounts file will look like {"test": {"username": "test", "password": "test"}, "test2": {"username": "test2", "password": "test2"}}

Filter array of nested object using javascript

I want to filter specific object using nested object element this
"token": "4f1f17f6503e4c5a3a269ecf93d6c92d"
This my data:
const data = [
{
name: "test",
token: {
expiryTime: "2021-09-24T12:27:30.654Z",
purpose: "ForgotPassword3",
token: "4f1f17f6503e4c5a3a269ecf93d6c92d",
},
user_id: "acaacc940c9ebfe798dee68acf5c",
zipcode: "",
},
{
name: "df ",
token: null,
user_id: "e0efe9810ca289ccd590bce48051",
zipcode: "",
},
{
name: "Io",
phone: "88888888",
state: "NY",
token: null,
user_id: "c88ce38d0c86f786c3a4b0f9f967",
zipcode: "13201",
},
];
Expected output is:
Data array inside the first object of token using filter object. Below given expected out.
const data = [
{
name: "test",
token: {
expiryTime: "2021-09-24T12:27:30.654Z",
purpose: "ForgotPassword3",
token: "4f1f17f6503e4c5a3a269ecf93d6c92d",
},
user_id: "acaacc940c9ebfe798dee68acf5c",
zipcode: "",
},
];
If you want a specific object, you could use find instead of filter. find will return the first element which verifies the condition specified to the find method where as the filter method is used to filters all the elements and returns all the element that matches the condition withing an array.
*You need to add the optional chaining ?. because the token object might be null like you have in some of your data
here both examples:
const data = [
{
"name": "test",
"token": {
"expiryTime": "2021-09-24T12:27:30.654Z",
"purpose": "ForgotPassword3",
"token": "4f1f17f6503e4c5a3a269ecf93d6c92d"
},
"user_id": "acaacc940c9ebfe798dee68acf5c",
"zipcode": ""
},
{
"name": "df ",
"token": null,
"user_id": "e0efe9810ca289ccd590bce48051",
"zipcode": ""
},
{
"name": "Io",
"phone": "88888888",
"state": "NY",
"token": null,
"user_id": "c88ce38d0c86f786c3a4b0f9f967",
"zipcode": "13201"
}
]
const resFilter = data.filter(x => x.token?.token === "4f1f17f6503e4c5a3a269ecf93d6c92d");
console.log(resFilter);
const resObj = data.find(x => x.token?.token === "4f1f17f6503e4c5a3a269ecf93d6c92d");
console.log(resObj);
You must use the following code
const finded = data.filter(user => user?.token?.token ==="value"})
console.log(finded);

Cannot fetch complete object

So i'm trying to get profile data using API in Node.js but seems never get complete objects (for example avatar is missing from response)
i tried to console.log the object it went perfectly fine
Here is the server code:
router.get('/users/me', auth, async (req, res) => {
try {
const me = await User.findById(req.user._id)
console.log(me)
res.send(me)
} catch (e) {
res.status(500).send(e)
}
})
Here is response on console:
{ avatar:
'https://wisapedia-uploads.s3.amazonaws.com/default_ava.png',
bookmarks: [],
trips: [],
verified: false,
_id: 5d67b4155a032f3450c8ca03,
name: 'Syauqi',
password:
'$2a$08$LwLJPrp6MPdffkpJ1T2iN.QFbMDU5gAsSceNZVzU8tfDe5aUjGfFO',
email: 'ahmadthariq#gmail.com',
number: 85786135661,
birthday: 1997-04-01T16:00:00.000Z,
tokens:
[ { _id: 5d67b4155a032f3450c8ca04,
token:
'eyJhbGciOiJIUzI1NiIsI4gdCI6IkpXVCJ9.eyJfaWQiOiI1ZDY3YjQxNTVhMDMyZjM0NTBjOGNhMDMiLCJpYXQiOjE1NjcwNzczOTd9.i-r2wB6BoqK7cSoIxBiWB6SSESoCk3S5G_sW5PMz09s' } ],
createdAt: 2019-08-29T11:16:37.516Z,
updatedAt: 2019-08-29T11:16:37.572Z,
__v: 1 }
Here is what i got on postman:
{
"bookmarks": [],
"trips": [],
"verified": false,
"_id": "5d67b4155a032f3450c8ca03",
"name": "Syauqi",
"email": "ahmadthariq#gmail.com",
"number": 85786135661,
"birthday": "1997-04-01T16:00:00.000Z",
"createdAt": "2019-08-29T11:16:37.516Z",
"updatedAt": "2019-08-29T11:16:37.572Z",
"__v": 1
}
Thank you

Testing values of array objects

If i have an array like:
[
{ "user": "tom",
"email": "ee#co.com"
},
{ "user": "james",
"email": "bb#co.com"
},
{ "user": "ryan",
"email": "rr#co.com"
}
]
But it's not always being returned in that order - how can i check if ryan, for example, exists somewhere in one of these objects?
If you are already using lodash (or want to) then I would use its find:
_.find(array, { user: "ryan" })
Or with a few more characters you can do it without lodash:
array.find(elem => elem.user === "ryan")
Both return undefined if a matching element is not found.
Function return true if array contains ryan.
var input = [
{ "user": "tom",
"email": "ee#co.com"
},
{ "user": "james",
"email": "bb#co.com"
},
{ "user": "ryan",
"email": "rr#co.com"
}
]
var output = input.some(function(eachRow){
return eachRow.user === 'ryan';
});
console.log(output);
My method to solve that is to extract the targeted fields into arrays then check the value.
const chai = require('chai');
const expect = chai.expect;
describe('unit test', function() {
it('runs test', function() {
const users = [
{ "user": "tom",
"email": "ee#co.com"
},
{ "user": "james",
"email": "bb#co.com"
},
{ "user": "ryan",
"email": "ryan#co.com"
}
];
const names = extractField(users, 'user'); // ['tom', 'james', 'ryan']
expect(names).to.include('ryan');
});
function extractField(users, fieldName) {
return users.map(user => user[fieldName]);
}
});
I'm using chai for assertion. In case you want to check in other fields, we just use the extract methods.
const emails = extractField(users, 'email');
expect(emails).to.include('ryan');
Hope it helps

NodeJs: Data Transformers like in Laravel PHP Framework

I've created multiple REST API projects using the Laravel framework and basing my code structure on the Laracasts tutorial. However we are deciding to move some projects using NodeJs as a backend. I'm beginning to learn node and I'm trying to replicate it in Node. I was able to do it for a singe object response but for multiple objects I can't seem to make it work.
Here is my controller:
index(req,res) {
User
.findAll()
.then(function(users){
res.json(api.respond(transfomer.transformCollection(users)));
})
.catch(function(error){
res.json(api.respondWithError('users not found',error));
});
}
api controller:
module.exports = {
// response w/o error
respond: function(data,msg,status) {
if (msg == null) {
return {
'status': status || true,
'data': data
};
} else {
return {
'status': true,
'message': msg,
'data': data
};
}
},
// response with error
respondWithError: function(msg,error) {
var self = this;
var status = false;
var data = {
'error': error
};
return this.respond(data,msg,status);
},
};
transformer.js
module.exports = {
// single transformation
transform (user) {
return {
'id' : user.id,
'username': user.username,
'firstname': user.firstname,
'lastname': user.lastname,
'address': user.address,
'phone': user.phone,
'mobile': user.mobile,
'status': user.status
};
},
//
transformCollection(users) {
var self = this;
var data = [];
for (var i = 0; i <= users.length; i++) {
data.push(this.transform(users[i]));
}
return data;
}
};
sample output
{
"status": true,
"data": [
{
"id": 1,
"username": "b#email.com",
"firstname": "Jon",
"lastname": "Doe",
"address": "Homes",
"phone": "+966501212121",
"mobile": "+966501212121",
"status": "NOT VERIFIED"
},
{
"id": 1,
"username": "b#email.com",
"firstname": "Jon",
"lastname": "Doe",
"address": "Homes",
"phone": "+966501212121",
"mobile": "+966501212121",
"status": "NOT VERIFIED"
},
{
"id": 1,
"username": "b#email.com",
"firstname": "Jon",
"lastname": "Doe",
"address": "Homes",
"phone": "+966501212121",
"mobile": "+966501212121",
"status": "NOT VERIFIED"
},
{
"id": 1,
"username": "b#email.com",
"firstname": "Jon",
"lastname": "Doe",
"address": "Homes",
"phone": "+966501212121",
"mobile": "+966501212121",
"status": "NOT VERIFIED"
},
]
}
Sorry for asking this as I'm a bit newb with node. Is it possible to achieve that output as I tried different ways but Im still getting errors. Btw I'm using sequelize for the database.
Thanks.
You can use this:
const options = {
raw: true,
attributes: ['id', 'name', 'code', 'createdAt','updatedAt']
};
country.findAndCountAll(options).then(querySnapshot => {
const total = querySnapshot.count;
resolve({
docs: querySnapshot.rows,
total: total
})
}).catch((err) => {
reject(err)
});
I've found the answer to my question since sequelize is returning the results as an object with additional properties aside from the database results I had to modify the controller to set and convert the results to raw in order for me to get the array of objects from the query results from the database.
index(req,res) {
User
.findAll({ raw: true }) // added "raw: true"
.then(function(users){
res.json(api.respond(transfomer.transformCollection(users)));
})
.catch(function(error){
res.json(api.respondWithError('users not found',error));
});
},
This will return the array of objects from the database and from there the data transformer is working properly. Thank you for all the help.

Categories

Resources