Res.Json returns duplicated array - mysql

I'm using react js with express as backend and mysql.
When i'm trying to show the data from the database with the next query I notice in the console of the browser that res.json returns two arrays
This is the code to get the data
export const allVehiculos = async (req,res) => {
try {
var query= "SELECT `idVehiculos`, `placa`, `codip`, `descp`, `anio`, `clase`, `color`, `motor`, `serie`, `marca` " +
"FROM vehiculos AS vehiculos " +
"INNER JOIN marcas as marcas " +
"on `Vehiculos`.`idMarca` = `marcas`.`id`"
const vehiculos = await db.query(query)
res.json(vehiculos)
} catch (error) {
res.json({message: error.message})
}
}
This is the code of the react component
const [vehiculos, setVehiculo] = useState([])
useEffect( () => {
getVehiculos();
}, [])
return(
vehiculos.map((item) => {
return(
<tr key={item.idVehiculos} className="table-row row-item">
<td>{item.placa}</td>
<td>{item.codip}</td>
<td>{item.descp}</td>
<td>{item.anio}</td>
<td>{item.clase}</td>
<td>{item.color}</td>
<td>{item.motor}</td>
<td>{item.serie}</td>
<td>{item.marca}</td>
</tr>
)})
)
Result of res.json
Info not showing
But, when I change
res.json(vehiculos)
to
res.json(vehiculos[0])
Then i got just one array and the information shows correctly
Info showing correctly
I don't know why res.json returns two arrays and how to get only one array
Sorry for my bad english,
I'm very new in this field.
Thanks.

Related

How to make html_url into hyperlinks from fetch/json

I am learning javascript and Json so please bear with me.
I have fetched certain json data and made it visible on my webpage. All this through my GitHub api. I have three repositories in total and each contain the name of the repository a description and a html_url. I would like to make the three html_url active. So the user can click directly on them and go to that repository. I've been trying and googling but have yet to have any success. Any tips would be hugely appreciated.
Below is my js code.
`
function load () {
element = document.getElementById("gitRepos");
element.classList.toggle("hide");
const loadingStatus = document.querySelector('#gitRepos')
let url = "https://api.github.com/users/PaulEvans78/repos"
async function getrepo() {
let response = await fetch(url);
const repoList = document.getElementById("gitRepos")
const links = document.getElementById("gitRepos")
if(response.ok) {
let data = await response.json();
loadingStatus.innerText = " "
console.log(data);
for (const item of data){
createRepoLi(repoList, item.name, item.html_url, item.description)
}
} else {
console.log("HTTP-Error: " + response.status);
}
}
function createRepoLi(repoList, name, html_url, description){
const li = document.createElement('li')
li.innerText = name + "\n " + html_url + "\n " + description
li.classList.add("gitHubStyle");
repoList.appendChild(li)
}
getrepo();
}
`

Error while saving JSON data to Firestore collection using cloud function

I am trying to insert array in my firebase collection from cloud function. I need to have multiple lines in one document so for each line i am inserting an array. Please check my attached screenshot where you can see line0 , same way i need to have Line1,Line2,Line3..,Line n in the same document.
for line0 i am passing array from code like below and its working fine.
admin.firestore().collection("qbContestWinners").add(
{
'cmpientryid': context.params.processId,
'qbid': '',
'qbsyncdate': '',
'qbsyncstatus': 'pending',
'Line0':
{
id: "0",
description: 'PRIZE AMOUNT',
amount: 1000,
accountrefid: contestresultData.qbcontestid,
accountrefname: contestresultData.qbcontestname,
contestresultId: context.params.processId,
},
})
when i am looping through data i am getting from another table , i am not able to generate proper JSON to insert.
below is how i am looping and creating JSON after getting data from another table.
i = 1;
admin.firestore().collection("results").where('cid', '==', 'LKRRk2XXXXXXXX')
.orderBy("rank", "asc").get().then(snapshots =>
{
snapshots.forEach(doc =>
{
const contestresultId = doc.id;
const prizeAmount = doc.data().prizeamt;
const userId = doc.data().userid;
const lineNum = "Line" + i;
console.log("new line numner is: ", lineNum);
console.log(`lineNum? ${lineNum}`);
const linetxt = "Line" + String(i);
const insertData = "{"+linetxt +
":{id:'" + i +
"', description: 'PRIZE AMOUNT'"+
", amount:" + prizeAmount + "," +
"accountrefid:"+ contestresultData.qbcontestid +","+
"accountrefname:'" +contestresultData.qbcontestname +"',"+
"contestresultId:'" + contestresultId +"'," +
"},}"
const finalInsert = JSON.stringify(insertData);
const finalJSON = JSON.parse(finalInsert);
admin.firestore().collection("qbContestWinners").doc(mainID).set(
finalInsert.toJSON(),
{
merge: true
});
i= i+1;
});
});
using this code i am getting error
finalInsert.toJSON is not a function
Actually, the Line0 field is a map and not an Array, see this doc for more details.
So, if you want to create similar fields (Line1, Line2, ...), you simply need to pass a JavaScript Object to the set() method, as follows:
snapshots.forEach(doc => {
const contestresultId = doc.id;
const prizeAmount = doc.data().prizeamt;
const userId = doc.data().userid;
const lineNum = "Line" + i;
console.log("new line numner is: ", lineNum);
console.log(`lineNum? ${lineNum}`);
const lineObj = {
id: i,
description: 'PRIZE AMOUNT',
accountrefid: contestresultData.qbcontestid, //Not sure if you have defined contestresultData somewhere...
//...
}
const dataObj = {};
dataObj["Line" + i] = lineObj // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors
admin.firestore().collection("qbContestWinners").doc(mainID).set(dataObj, {merge: true});
i= i+1;
});
HOWEVER, note that you must return a promise that resolves when all the asynchronous work in your Cloud Function is complete (i.e. call to the Firestore set() method).
This is explained in the official Firebase video series, watch in particular the three videos titled "Learn JavaScript Promises".
Since you are calling several times the set() method in a forEach loop, you need to use Promise.all() in order to return a Promise when all these parallel calls to the set() method are completed.
The following should do the trick:
let i = 1;
return admin.firestore().collection("results") // <-- See the return here
.where('cid', '==', 'LKRRk2XXXXXXXX')
.orderBy("rank", "asc").get()
.then(snapshots => {
const promises = [];
snapshots.forEach(doc => {
const contestresultId = doc.id;
const prizeAmount = doc.data().prizeamt;
const userId = doc.data().userid;
const lineNum = "Line" + i;
const lineObj = {
id: i,
description: 'PRIZE AMOUNT',
accountrefid: contestresultData.qbcontestid,
//...
}
const dataObj = {};
dataObj[lineNum] = lineObj;
promises.push(admin.firestore().collection("qbContestWinners").doc(mainID).set(dataObj, {merge: true}));
i= i+1;
});
return Promise.all(promises) // <-- See the return here
});
A last remark: if mainID keeps the same value in the snapshots.forEach loop, you may adopt a totally different approach, consisting in building a JavaScript object with several LineXX properties and call the set() method only once. Since you didn't share the entire code of your Cloud Function it is impossible to say if this approach should be used or not.
first to the error
You stringify and parse a string. The problem here seems to be the order. You have to parse a "String" and to stringify an "Object". The result won't have a toJSON Method as well, but u can just stringify the Object to get a json.
the second thing
Why do you use a string to create your object? You shouldn't. Just use an object.
the third thing
You should not use Objects as Arrays. Not even in firebase.
Just use arrays. Example:
[Line0Object, Line1Object, ...]
Hint: If your array can work as its own collection. Just use a SubCollection. This might fit your needs.

How to get data from database in array format using node js and MySql

I am using node.js as server language and Mysql as database so I am running query and getting data from database but is is showing in format like this
[ BinaryRow { name: 'Dheeraj', amount: '77.0000' },
BinaryRow { name: 'Raju', amount: '255.0000' } ]
What I want is
['Dheeraj', 77.0000],
['Raju', 66255.000030],
This what I am doing in my backend (node.js):
My model:
static getChartData(phoneNo, userType) {
let sql = 'select businessname as name,sum(billamt) amount from cashbackdispdets where consphoneno =' + phoneNo + ' group by businessid order by tstime desc limit 10'
return db.execute(sql, [phoneNo]);
My controller:
exports.getColumnChart = function(req, res) {
const phoneNo = req.body.userId
const userType = req.body.userType
console.log(phoneNo)
dashboardModule.getChartData(phoneNo, userType)
.then(([rows]) => {
if (rows.length > 0) {
console.log(rows)
return res.json(rows)
} else {
console.log("error")
return res.status(404).json({ error: 'Phone No. already taken' })
}
})
.catch((error) => {
console.log(error)
return res.status(404).json({ error: 'Something went wrong !!' })
})
}
I am sending this data to Ui and when I am receiving it on UI it is in the form of object inside array which is not the required data type I want
axios().post('/api/v1/Dashboard/DashboardColumnChart',this.form)
.then(res=>{
console.log(res.data)
debugger
this.chartData= res.data
})
The above code consoles on browser like
I am not getting any idea how o do it should I do it with backend or with front end and how
Nodejs will send you a JSON response if you want to change it. It is better to change or maniuplate it in a Front end framework. But if you want to change it in backend as you have asked Make sure that the rows is in the format that you want to recive.
let data = [
{ "name": "Dheeraj", "amount": "77.0000" },
{ "name": "Raju", "amount": "255.0000" }
]
// empty array to store the data
let testData = [];
data.forEach(element => {
testData.push(element.name)
});
You can format it using array.map and Object.values. map functions loops over each element and returns a modified element according to the callback provided. Object.values simply returns all the values of an object in an array.
const data = [ { "name": "Dheeraj", "amount": "77.0000" }, { "name": "Raju", "amount": "255.0000" } ];
const formattedData = data.map(obj => Object.values(obj));
console.log("Initial Data: ", data);
console.log("Formatted Data: ", formattedData);
// Map function example
const a = [1,2,3]
const mappedA = a.map(e => e * 2)
console.log(a, " mapped to: ", mappedA);
// Object.values example
const b = { firstName: 'John', lastName: 'Doe', number: '120120' }
console.log(Object.values(b));

Unable to change the value of Filtered data length in angular4

I want to change the count of the filterdata [i.e. [(ngModel)]="filterdata"] after the data has arrived in the tables. For Example:
Initially in the text-box, i entered "experia" so all the data from the database that has experia appeared in the table. And the number of data is displayed on the right-hand of the table as you can see in the picture => "Number of searched data = 6". However, the issue is, if i enter text again in the search-text box and the data filters, but this filtered data number is not displayed, like "Number of searched data =4", of course this number will be less than the maximum number i.e.=6.It remains the same as >> "Number of searched data = 6" even though the total data displayed number is 4.
I have used an (ngModelChange) because i thought it might work, but it doesn't.
code:
transaction.component.html
<input class="form-control" id="input1-group1" style="margin-
top:20px" type="text" name="search" placeholder="Enter Search Text"
[(ngModel)]="filterdata" (ngModelChange)=
"countFilter(filterdata)"(keyup.enter)="searchByText(filterdata)">
//code
<h2> Transaction </h2>
<label *ngIf="toShowCount" id="arrayCountId"> Number of searched
data : {{arrayCount}}</label>
transaction.component.ts
countFilter(filtData){
console.log("inside countFilter = "+ filtData)
this.countFilterData = filtData.length;
if(this.arrayCount>=0){
if(this.countFilterData<this.arrayCount){
var result = [];
var url = config.url;
var port = config.port;
this.http.post("http://" + url + ":" + port +
"/transaction/masterSearchTransactionForm/", this.filterObj
, { headers: new Headers({ 'Authorization': 'Bearer ' +
localStorage.getItem('Token') }) })
.map(result => this.result = result.json())
.subscribe((res: Response) => {
console.log("# DATE FILTER RESULT TRANSACTION XXXXXXXXXXXX",
res);
this.records = res;
this.toShowCount =true;
console.log ("the result of SearchByText is = ", this.result)
this.arrayCount = this.result.length;
console.log("ArrayCount = " , this.arrayCount)
console.log("search-by-text records = ",res)
console.log("Search by Text result is : " + result)
if (this.result.length > 0) {
this.notify.Success("Data Displayed Successfully");
this.loading = false;
}
else {
this.notify.Error("No Matching Data Available")
this.loading = false;
}
});
}
}
You don't need (ngModelChange)="countFilter(filterdata)" because as i can see you have 2 methods that call REST endpoint for filtering data: one in countFilter(filterdata) and the other one in searchByText(filterdata). When you call searchByText(filterdata) i presume that you are trying to filter data on server and get results. When you get that result from server, than you put length of that result in variable like you did in countFilter method.
this.arrayCount = this.result.length;
just put this in searchByText method and remove countFilter because you do not need it.
EDIT:
<input class="form-control" id="input1-group1" style="margin-
top:20px" type="text" name="search" placeholder="Enter Search Text"
#searchControl (keyup.enter)="searchByText(searchControl.value)"
(input)="countFilter($event.target.value)"
>
in your .ts file you will have a method searchByText(value) that calls API endpoint and query data table, something like this:
searchByText(value) {
this.http.post("http://" + url + ":" + port +
"/transaction/masterSearchTransactionForm/", this.filterObj
, { headers: new Headers({ 'Authorization': 'Bearer ' +
localStorage.getItem('Token') }) })
.map(result => this.result = result.json())
.subscribe((res: Response) => {
this.records = res;
}
Now , you have saved all data that you queried first time with ENTER click
After this you want to have method that can filter through this saved data:
countFilter(value) {
this.records = this.records.filter((record) => record.name == value);
}
now you have a same variable (this.records) with filtered data! And in html you can just do string interpolation {{this.records.length}}

Extract Value from Json string in Ionic 2

I am using OAuth2 for authorization in my Ionic 2 App and the decoded token response(which I am getting from the BASE64.decode() function) is like the below(key-value form).I am storing it in a variable called 'tokendata' of type 'any'. Now I want to extract values from this decoded token. Now if I simply do 'tokendata.personnelnbr', it is not working. Also if I do a 'json.parse(tokendata) or a json.parse('tokendata'), store it in another variable say 'myVar' and then try to access 'myVar.personnelnbr', then also it is not working. Please help with the solution!
{
"client_id":"xxx",
"scope":"user_profile",
"sub":"yyy",
"amr":"external",
"auth_time":1499753830,
"idp":"eso_enterprise",
"upn":"yyy",
"email":"yyy",
"samaccount_name":"yyy",
"peoplekey":"1169",
"personnelnbr":"1108",
"given_name":"Deblina",
"sn":"Dutta Chowdhury",
"exp":1499,
"nbf":1499
}
The method where I am trying to access the 'personnelnbr' field is given below:
private initializeApp(): void
{
this.platform.ready().then(() => {
console.log("Before login Deblina");
/**
* Read in app configuration, get an oAuthV1 ESO token, register device with REBAR Notification Services
*/
this.configService.Initialize().subscribe(
() => this.esoService.getV2Token().subscribe(
(v2Token) => {
this.tokendata = BASE64.decode(v2Token);
alert("Token Deblina decoded: " + BASE64.decode(v2Token));
console.log("Token Deblina decoded: " + BASE64.decode(v2Token));
this.concatenatedToken = "'" +this.tokendata+ "'";
alert(this.concatenatedToken);
console.log(this.concatenatedToken);
this.myVar = JSON.parse(this.tokendata);
alert("Now:" + this.myVar.personnelnbr);
console.log("Now:" + this.myVar.personnelnbr);
this.myVar = JSON.parse(this.concatenatedToken);
alert("Now:" + this.myVar.personnelnbr);
console.log("Now:" + this.myVar.personnelnbr);
},
(error) => console.log(error),
() => { this.nav.setRoot(HomePage)}
),
(error) => console.log(error)
);
});
}
If you just want to to extract value, you can do this:
let datas = {
"client_id":"xxx",
"scope":"user_profile",
"sub":"yyy",
"amr":"external",
"auth_time":1499753830,
"idp":"eso_enterprise",
"upn":"yyy",
"email":"yyy",
"samaccount_name":"yyy",
"peoplekey":"1169",
"personnelnbr":"1108",
"given_name":"Deblina",
"sn":"Dutta Chowdhury",
"exp":1499,
"nbf":1499
};
for (let key in datas) {
console.log(key + " => " + datas[key]);
}