I am stuck on this problem from quiet sometime. I have created a table with 3 columns out of which the for two columns I can use prop property to display the contents of each row for those two columns. Now, for the third column, I want to display contents from another array, how do I display this information in the third column.
Please find the example of the code below:
This is the HTML Code
<el-table :data = "data_table">
<el-table-column
prop = "Id"
label= "Unique ID">
</el-table-column>
<el-table-column
prop = "color"
label = "Color">
</el-table-column>
<el-table-column
prop = ""
label = "Count">
<template slot-scope="scope">
<el-button type="text" #click="dialogVisible = true; get_total_count_users(scope.row)">{{users.length}}</el-button>
<!--Skipping the code for dialog box..I have tested that part pretty well, so I know it works. -->
</template>
</el-table-column>
</el-table>
This is the javascript part of the code:
<script>
export default {
data(){
return{
data_table:[], // I fill the data_table array using some AJAX/Axios calls which has props Id and Color.
users: [], // I fill the users array using some AJAX/Axios calls which has multiple user information.
};
},
methods:{
get_total_count_users(row){
// axios call, etc. This part works successfully, I checked the values.
}
}
</script>
A little explanation for the above code:
I make an AJAX/Axios call to an API which return me a list/array of value in data-table array. It had two props in it, that is Id and Color. I make another axios/AJX call to an api which returns me the list of the users based on the Id present on that row of the table. Each row will have a unique Id. Using that Id, I make an axios call to an api .. example, www.example/{{Id}}.com .This returns me a list of users linked to that id. Now, my next task is to display the total users (by taking the length of the users array) and displaying it as a button. But, as I am not using prop to display the values (length of users array for each row), the value in the button is displayed the same through all the rows. It keeps changing for the entire column if I click a button on any of the rows.
get_total_count_users(scope.row) function is used to make an axios/AJAX call to www.example/{{Id}}.com and stores multiple user information tied with that Id in users array.
Please refer to the image below:
Initially, all values are 0, as the Id in the first row has 0 users attached to it.
When I click on the 3rd rows button (which initially has 0 in it), all the values in that column change to 2, as the Id in the 3rd row has two users tied to it.
Hence, the issue here is that, I simply want to display total number of users (count) each row based on that id without using the prop property.
Hope the above explanation and example is helpful to understand the problem.
Any help would be appreciated.
The answer will solve the problem but is not a specific solution that is defined to get data from multiple arrays into your data table.
You can chain your axios responses and then use a foreach to add the variables to your object inside array.
So I am assuming that you are calling a method on mount like this:
data: () => ({ tableData: [] }),
mounted() {
this.getData();
}
now within your getData() function make different axios calls and put your response into the table, with something like this.
methods: {
getData() {
var myTableData = [];
axios({ method: 'GET', url: 'http://first-url', headers: [...] }).then(res => {
//we have got the table data here
myTableData = res.data;
//looping through data and making axios calls based on data.
myTableData.foreach((row, index) => {
var newUrl = 'https://getdatafrom.com/'+ row.id+'/'; //using the data from previous call.
axios({ method: 'GET', url: newUrl, headers: [...]}).then(res2 => {
var counts = res.data;
// adding variable myCount to the table data array.
row.myCount = counts[index];
}).catch(err => { console.error(err)})
})
// setting data object
this.tableData = myTableData;
}).catch(err => { console.error(err) })
}
}
let me know if you have any issue.
Given this query here,
let output = [];
const sql = `select * from coredb.account LIMIT ${offset},${limit}`;
let data = await sequelize.query(sql, null, {raw: true, type: sequelize.QueryTypes.SELECT});
data.forEach((item) => {
console.log(item['id'], item.id); // <-- output says "undefined, undefined"
});
the data variable is indeed hydrated with the right row data when using console.log to inspect it.
But, when I try to access the individual properties, they only ever come back as undefined. This TextRow object that Sequelize seems to return the result in doesn't seem to want to let me access then explicit rows.
Just curious what i'm missing here, am I missing an option?
I agree, Sequalize raw queries are not intuitive. You don't need the null or raw: true flag. Something like this should work:
let data = await sequelize.query(sql, {type: sequelize.QueryTypes.SELECT});
When I tried this, "data" was an array of two objects, each being the query result. So, the properties can be accessed by using index [0].... e.g.
data[0].forEach((item) => {
console.log(item['id'], item.id); // <-- output says "undefined, undefined"
});
Not yet sure WHY this occurs!
EDIT - it's because .query() should have only two arguments. Changing the call to: sequelize.query(sql, {raw: true, type: sequelize.QueryTypes.SELECT}) resulted in data being a single array (as expected).
Finally I was able to find the solution for it.
You just need to make a new array and push data into it by finding bases on key name like this:
suppose we have data in students object:
let finalArray = new Array();
for (var k in students ) {
finalArray.push(students[k])
}
console.log(finalArray) // Normal JSON array object :)
m.sequelize.query(sql, {
model,
mapToModel: true
})
.then(model => res.status(200).send(model))
.catch(error => res.status(400).send(error.toString())
})
I have managed to retrieve data from Firebase, however, I am unable to store the data into a variable I have declared. I want to store in a variable is so that I am able to use at another method.
Please help.
These are the codes that I have tried.
1st method, rest api
retrieveUser(){
this.restProvider.retrieveUser(this.emailAdd, this.pw)
.subscribe(listUser => {
this.users = userList.results //trying to store to users variable
console.log(listUser);
},
err => {
console.log(err);
},
() => console.log('success')
);}
2nd method to use for some IF-ELSE
loginBtnPress(event){
this.retrieveUser();
console.log(this.users);
}
You are doing it wrong. this.users is getting updated using observables. So, if you try to retrieve its value before the value has been updated, you wont get it as expected. You can call it as below,
retrieveUser(){
this.restProvider.retrieveUser(this.emailAdd, this.pw)
.subscribe(listUser => {
this.users = userList.results //trying to store to users variable
callYourMethodWithUpdatedValue(this.users); // <-- Pass value here
},
err => {
console.log(err);
},
() => console.log('success')
);}
The callYourMethodWithUpdatedValue is called every time(and as soon as) the value this.users is updated
Update 1
You can't retrieve async value in one method and expect that value to be used in some other method on button click. Reason being, your are expecting value on that button click , but since its a async call (can take n secs), you can't be assured that the value will be populated when the value is used through some button call.
That's wrong implementation. You need to change the architecture to either of below:
Don't route to that page unless the user value has been resolved (received). Check canActivate and canActivateChildren.
Change the UX where you are trying to retrieve the use async variable on button click, and activate the button when the value has been received (Here you can use Subject ). Something like this demo
I have two Json files that I exported from wordpress that have corresponding ID's I want to combine them into one Json file so I can bring it into website I am building with Gatsby JS. One of the files is the posts.json and the other is postsMeta.json. The post_id in postsMeta corresponds with the ID in Posts
How would I best go about merging the two? Can I run some sort of for loop in js and how would I so? I am on windows is there a json explorer of some sorts that could help me do this.
lastly I would also like to trim out some of the unnecasry fiels such as post_parent in the posts json and something like the meta_key in the postsMeta json.
Ok hopefully this is clear enough, thanks in advance.
Here is an example of the first object corresponding pairs in the two files
posts.json
{"ID":"19","post_author":"2","post_date":"2010-12-31 23:02:04","post_date_gmt":"2010-12-31 23:02:04","post_content":"Harry Potter was not available for the first sitting of the Halloween Picture. I hope everyone had a safe and fun Halloween. Tomorrow is picture retake day, please send back your previous prints if you want retakes. It is also hot lunch. See You tomorrow!","post_title":"Happy Halloween","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"open","post_password":"","post_name":"happy-halloween","to_ping":"","pinged":"","post_modified":"2011-01-03 05:26:11","post_modified_gmt":"2011-01-03 05:26:11","post_content_filtered":"","post_parent":"0","guid":"http:\/\/localhost\/mrskitson.ca_wordpress\/?p=19","menu_order":"0","post_type":"post","post_mime_type":"","comment_count":"1"},
postsMeta.json
{"meta_id":"27","post_id":"19","meta_key":"large_preview","meta_value":"http:\/\/www.mrskitson.ca\/wp-content\/uploads\/2010\/12\/halloween.jpg"},
Update:
this is an attempt to solve this problem with the current answer, you can edit the code there.
How would I best go about merging the two?
Is it mandatory for you combine the two JSON files/data?
Because you could just require or load the JSON data from within your script (or even put them in the HTML) and then to get the meta value of a specific meta field/key, this function could do that:
// `single` has no effect if `meta_key` is empty.
function getPostMeta( post_id, meta_key, single ) {
let id = String( post_id ),
pm = [];
postsMeta.map( m => {
let a = ( ! meta_key ) ||
( meta_key === m.meta_key );
if ( a && id === m.post_id ) {
pm.push( m );
}
});
let meta = {},
mk = {};
pm.map( m => {
let k = m.meta_key, v;
if ( undefined === meta[ k ] ) {
meta[ k ] = m.meta_value;
} else {
v = meta[ k ];
if ( undefined === mk[ k ] ) {
meta[ k ] = [ v ];
mk[ k ] = 1;
}
meta[ k ].push( m.meta_value );
m[ k ]++;
}
});
pm = null;
mk = meta_key ? mk[ meta_key ] : null;
if ( mk ) {
return single ?
meta[ meta_key ][0] : // Returns a single meta value.
meta[ meta_key ]; // Returns all the meta values.
}
return meta_key ?
meta[ meta_key ] : // Returns the value of the `meta_key`.
meta; // Or returns all the post's meta data.
}
The data I used for testing: (take note of the postsMeta in the above/getPostMeta() function)
// Array of `post` objects.
const posts = [{"ID":"19","post_author":"2","post_date":"2010-12-31 23:02:04","post_date_gmt":"2010-12-31 23:02:04","post_content":"Harry Potter was not available for the first sitting of the Halloween Picture. I hope everyone had a safe and fun Halloween. Tomorrow is picture retake day, please send back your previous prints if you want retakes. It is also hot lunch. See You tomorrow!","post_title":"Happy Halloween","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"open","post_password":"","post_name":"happy-halloween","to_ping":"","pinged":"","post_modified":"2011-01-03 05:26:11","post_modified_gmt":"2011-01-03 05:26:11","post_content_filtered":"","post_parent":"0","guid":"http:\/\/localhost\/mrskitson.ca_wordpress\/?p=19","menu_order":"0","post_type":"post","post_mime_type":"","comment_count":"1"}];
// Array of `meta` objects.
const postsMeta = [{"meta_id":"27","post_id":"19","meta_key":"large_preview","meta_value":"http:\/\/www.mrskitson.ca\/wp-content\/uploads\/2010\/12\/halloween.jpg"},{"meta_id":"28","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/facebook.com"},{"meta_id":"29","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/twitter.com"},{"meta_id":"30","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/linkedin.com"}];
Examples: (see this Fiddle for demo)
// In these examples, we are retrieving the meta value for the post #19 (i.e. ID is 19).
// Retrieve a single value.
// Returns mixed; string, number, etc.
let url = getPostMeta( 19, 'large_preview', true );
console.log( url );
// Retrieve all meta values.
// Always returns an array of values.
let ms = getPostMeta( 19, 'many_values' );
console.log( ms, ms[0] );
// Retrieve all meta data.
// Always returns an object with meta_key => meta_value pairs. I.e. { key => value, ... }
let ma = getPostMeta( 19 );
console.log( ma, ma.large_preview, ma.many_values[0] );
But if you really must combine the JSON data, you can do: (again, see demo on the same Fiddle)
// Here we modify the original `posts` object.
posts.map( p => {
// Add all the post's meta data.
p.meta = getPostMeta( p.ID );
// Delete items you don't want..
delete p.post_parent;
delete p.menu_order;
// delete ...;
});
console.log( JSON.stringify( posts[0].meta ) ); // posts[0].meta = object
console.log( posts[0].post_parent, posts[0].menu_order ); // both are undefined
And then if you want to copy-paste the new/merged JSON data:
JSON.stringify( posts );
But if you actually just want to do something with the post's meta, you can loop through the posts object and do the thing; e.g.:
// Here the original `posts` object is not modified, and that we don't
// (though you can) repeatedly call `getPostMeta()` for the same post.
posts.map( p => {
// Get all the post's meta data.
let meta = getPostMeta( p.ID );
// Do something with `meta`.
console.log( meta.large_preview );
});
console.log( JSON.stringify( posts[0].meta ) ); // posts[0].meta = undefined
console.log( posts[0].post_parent, posts[0].menu_order ); // both still defined
// posts[0].meta wouldn't be undefined if of course posts[0] had a `meta` item,
// which was set in/via WordPress...
If you can do this in js, there's a pretty easy approach using Array#map. If you simplify your question, you're really asking how to add this meta data under each entry in posts, and get only the fields you want.
I'm assuming the posts.json is actually an array (e.g. [{"ID":"19"....).
// Load these server-side, fetch them remotely, copy-paste, etc.
// I'll require them here for simplicity
const posts = require('./posts.json');
const postsMeta = require('./postsMeta.json');
// Build a Map so we can quickly look up the metas by post_id
// Extract what we need by destructuring the args
const metaByPost = postsMeta.reduce((a, {
post_id: id,
meta_value: value,
}) => a.set(id, {
value,
/* anything else you want in here */,
}), new Map());
const mergedPosts = posts.map(post => ({
// Spread in the post
...post,
// Spread in the meta content
...metaByPost.get(post.ID),
// Undefine the props we don't want
post_parent: undefined,
}));
I don't love manually setting stuff to undefined -- I think it's nicer to explicitly say what props you're going to include, instead of loading everything and undefining certain props.
Try this snippet directly in the Chrome DevTools console:
(function(
postsUrl='https://cdn.glitch.com/61300ea6-6cc4-4cb6-a62f-31adc62ea5cc%2Fposts.json?1525386749382',
metaUrl='https://cdn.glitch.com/61300ea6-6cc4-4cb6-a62f-31adc62ea5cc%2Fpostmeta.json?1525386742630'
) {
Promise.all([
fetch(postsUrl).then(r => r.json()),
fetch(metaUrl).then(r => r.json()),
]).then(([postsResponse, metaResponse]) => {
// Inspected the actual JSON response to come up with the data structure
const posts = postsResponse[2].data;
const meta = metaResponse[2].data;
const metaByPostId = meta.reduce((accum, el) => {
accum[el.post_id] = el;
return accum;
}, {});
const transformedPosts = posts.map(post => {
const merged = {
...post,
...(metaByPostId[post.ID] || {}),
};
delete merged.post_parent;
// delete any other fields not wanted in the result
return merged;
});
console.log(transformedPosts);
});
})();
replace URLs accordingly, I used the ones from Glitch example here
as commented, actual data is buried in response[2].data. Use Network tab / Parsed view to see structure
replace console.log with copy, if you want the result copied to clipboard, instead of logged to console
Blunt to the point for your question. We want to:
merge var a = {/*some json*/} into var b = {/*another json*/}
trim fields in var exclusions = ["post_parent","meta_key"]
Merge the JSONS
First, we need to populate a and b.
Your JSONs are parsable into Javascript objects with JSON.parse():
let a = JSON.parse(/*JSON here*/);
let b = JSON.parse(/*JSON here*/);
Because how properties are defined in Javascript, if you define a property again, the second definition will overwrite the first. Your JSONS contain only strings as keys and strings as values, so a shallow copy will suffice. Object.assign() will copy all the properties (field and values) into the first argument and return the final Object. Therefore this will merge a into b, assuming they have different keys, else the values in b will overwrite values in a:
a = Object.assign(a,b);
Otherwise, if they are not disjoint, you have to define some policy on how to join, for example may prioritize one. Below, we keep the values in a instead:
a = Object.assign(b,a);
Since you mentionmed a for loop, the line below does the same as two code lines above and will also allow show you an example on how to write your own custom lambda expression:
Object.keys(a).forEach(k=>b[k]=b[k]?b[k]:a[k]);
Do not wish to touch a and b? Create a third object c.
let c = Object.assign({},a,b)
Lastly (wait until the trim step below is accomplished) JSON.stringify() will convert your merged object back into JSON.
Trim exclusions
Following the third example, we have c merged with all the fields.
First a little hack taken from here:
Object.filter = (obj, predicate) => Object.keys(obj)
.filter( key => predicate(obj[key]))
.reduce( (res, key) => (res[key] = obj[key], res), {} );
Now Objects, just like arrays have a filter prototype, having extended Object prototype. It is not really best practice since this will extend every Object but this function works quite well with respects to the semantics of Javascript and this example serves as an opportunity to keep elegant Javascript styles code:
c = Object.filter(c, key=> !exclusions.includes(key) );
Voit-lá, done.
As for defined Object.filter() it uses Array.filter() and Array.reduce() . Click for reference, for your convenience.
Using DBIx::Class, I found a solution to my issue, thankfully. But I'm sure there has to be a nicer way.
my $record = $schema->resultset("food")->create({name=>"bacon"});
How would I turn this record into a simple hashref instead of having to make this call right after.
my record = $schema->resultset("food")->search({name=>"bacon"})->hashref_array();
Ideally I want to be able to write a code snippet as simple as
{record=> $record}
instead of
{record => {name => $record->name, $record->food_id, ...}}
This would drive me insane with a table that has alot more columns.
I assume you're talking about DBIx::Class?
my $record = $schema->resultset("food")->create({name=>"bacon"});
my %record_columns = $record->get_columns;
# or, to get a HashRef directly
my $cols = { $record->get_columns };
# or, as you've asked for
my $foo = { record => { $record->get_columns } };
What you're looking for is included in DBIx::Class as DBIx::Class::ResultClass::HashRefInflator.