How to construct multiple dictionaries to array in react native - arrays

I am trying to show Expand/Collapse Flatlist data in react-native.
It is like single parent with multiple childs. So, If user tap on the cell, I have to show multiple rows for that expand/collapse.
But, I am getting data from server like following.
[{
code: '1212',
name: 'Bajaj Model 1',
url: 'Some url',
category: 'Bike'
},
{
code: '1213',
name: 'Bajaj Model 2',
url: 'other url',
category: 'Bike'
},
{
code: '1454',
name: 'BMW Model 1',
url: 'Some url',
category: 'Car'
},
{
code: '1454',
name: 'BMW Model 2',
url: 'Some url',
category: 'Car'
}
]
So, All the Bike data, I have to show one place like Parent and child.
For that I have done filter.
const fundsFilterData = mapValues(groupBy(response, 'category'),
fundslist => fundslist.map(item => omit(item, 'category')));
And I am getting like following.
{
'Bike': [{
code: '1212',
name: 'Bajaj Model 1',
url: 'Some url'
},
{
code: '1213',
name: 'Bajaj Model 2',
url: 'other url'
},
],
'Car': [{
code: '1454',
name: 'BMW Model 1',
url: 'Some url'
},
{
code: '1454',
name: 'BMW Model 2',
url: 'other url'
},
]
}
But, I want to make it as array along with some pre added keys like following.
[{
'Title': 'Bike',
'Values': [{
'code': '1212',
'name': 'Bajaj Model 1',
'url': 'Some url'
},
{
'code': '1454',
'name': 'Bajaj Model 2',
'url': 'other url'
}
]
},
{
'Title': 'Car',
'Values': [{
'code": '
1454 ',
'name": '
BMW Model 1 ',
'url": '
Some url '
},
{
'code': '1454',
'name': 'BMW Model 2',
'url': 'Some url'
}
]
}
}
So that I can show Titles in headers and once user tap on row, I can show child's data as expanded.
Any suggestions?

Use _.map() which returns an array, and not _.mapValues(). In the _.map() get the Title (the key) from the 2nd param. Use it and the values (after _.omit()) to construct an object for each group.
const { map, groupBy, omit } = _;
const response = [{"code":"1212","name":"Bajaj Model 1","url":"Some url","category":"Bike"},{"code":"1213","name":"Bajaj Model 2","url":"other url","category":"Bike"},{"code":"1454","name":"BMW Model 1","url":"Some url","category":"Car"},{"code":"1454","name":"BMW Model 2","url":"Some url","category":"Car"}];
const fundsFilterData = map(
groupBy(response, 'category'),
(list, Title) => ({
Title,
Values: list.map(item => omit(item, 'category'))
})
);
console.log(fundsFilterData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Related

unexpected token ",", expected expression in sanity studio vision

I am following a course on react native and We are using Sanity as our backend. I have already set the schemas and made the adjustments in my Sanity Studio.
HERE IS MY FEATURED SCHEMA CODE:
export default {
name: 'featured',
title: 'featured Menu Categories',
type: 'document',
fields: [
{
name: 'name',
type: 'string',
title: 'Featured category name',
validation: (Role) => Role.required(),
},
{
name: 'short_description',
type: 'string',
title: 'Short description',
validation: (Role) => Role.max(200),
},
{
name: 'restuarants',
type: 'array',
title: 'Restuarants',
of: [{ type: 'reference', to: [{ type: 'restuarant' }] }],
},
],
};
HERE IS MY RESTAURANT SCHEMA CODE:
export default {
name: 'restaurant',
title: 'Restuarant',
type: 'document',
fields: [
{
name: 'name',
type: 'string',
title: 'Restuarant name',
validation: (Role) => Role.required(),
},
{
name: 'short_description',
type: 'string',
title: 'Short description',
validation: (Role) => Role.max(200),
},
{
name: 'image',
type: 'image',
title: 'Image of the Restuarant',
},
{
name: 'lat',
type: 'number',
title: 'latitude of the restaurant',
},
{
name: 'long',
type: 'number',
title: 'longitude of the restaurant,
},
{
name: 'address',
type: 'string',
title: 'Address of the Restuarant',
validation: (Role) => Role.required(),
},
{
name: 'rating',
type: 'number',
title: 'Enter a rating of (1 - 5)',
validation: (Role) =>
Role.required()
.min(1)
.max(5)
.error('please enter a number between 1 - 5'),
},
{
name: 'type',
type: 'string',
title: 'Category',
validation: (Role) => Role.required(),
type: 'reference',
to: [{ type: 'category' }],
},
{
name: 'dishes',
type: 'array',
title: 'Dishes',
of: [{ type: 'reference', to: [{ type: 'dish' }] }],
},
],
};
I also did one for the dish and category.
Then I went to my Sanity Studio to fill in my restaurant schema fields;
After I went to my Vision Board in Sanity Studio and did a query(Just like the instructor):
*[_type == "featured"]{
...,
restuarants[]=> {
...,
dishes[]=> ,
type=> {
name
}
},
}
And I got an error of:
unexpected token ",", expected expression ;
I did what any developer would have done if they got an error. I double-checked my code and compared it to the instructor in the video. (I still got the error). Then I googled it(And found no answer). It's been 2 days now and I still haven't found anything.
This is my first querying in Sanity and I am not sure what I am doing wrong with my query. Can anyone please help me? Thanks.
As the error mentioned, you missed a ' in your schema code.
Keep a ' after restaurant
{
name: 'long',
type: 'number',
title: 'longitude of the restaurant',
},
No worries I found the answer to my problem. The problem was with my querying.
HERE WAS MY CODE BEFORE:
*[_type == "featured"]{
...,
restuarants[]=> {
...,
dishes[]=> ,
type=> {
name
}
},
}
THIS IS HOW I WAS SUPPOSED TO WRITE IT:
*[_type == "featured"]{
...,
restuarants[]-> {
...,
dishes[] -> ,
type-> {
name
}
},
}
I was supposed to use a straight line instead of an equal sign.
I hope this helps anyone who runs into this problem

Search does not work for link text in material table

below is my code:
const data = [];
Object.keys(json).forEach(key => {
const jobStr = json[key];
console.log(`=== historicalJobCallback jobStr: ${jobStr}`);
const jobItem = jobStr.split(',');
data.push({
jobId: <a href={Utils.getLungoEndpoint() + jobItem[0]} target="_blank" rel="noopener noreferrer"
className={classes.link}>{jobItem[0]}</a>,
jobName: jobItem[1],
submittedBy: jobItem[2],
submittedTime: jobItem[3],
tenant: jobItem[4],
business: jobItem[5]
})
});
setState({
columns: [
{
title: 'Job ID',
field: 'jobId',
render: rowData => <a href={Utils.getLungoEndpoint() + jobItem[0]} target="_blank"
className={classes.link}>{jobItem[0]}</a>
},
{title: 'Job Name', field: 'jobName'},
{title: 'Submitted By', field: 'submittedBy'},
{title: 'Submitted Time', field: 'submittedTime'},
{title: 'Tenant', field: 'tenant'},
{title: 'Business', field: 'business'},
],
data: data
});
As you can see the jobId column is a link, the search feature works for other columns except the job id column, I suspect it is due to the job id text is wrapped in a link, how can I make it searchable?
thanks for the suggestion by #Yatrix, made my code like below and the search is now working for link:
Object.keys(json).forEach(key => {
const jobItem = json[key].split(',');
data.push({
jobId: {
name: jobItem[0],
url: Utils.getLungoEndpoint() + jobItem[0]
},
jobName: jobItem[1],
submittedBy: jobItem[2],
submittedTime: jobItem[3],
tenant: jobItem[4],
business: jobItem[5]
})
});
console.log(`=== historicalJobCallback data: ${JSON.stringify(data)}`);
setState({
columns: [
{
title: 'Job ID',
field: 'jobId',
customFilterAndSearch: (term, rowData) => (rowData.jobId.name).indexOf(term) != -1,
render: rowData => <Link href={rowData.jobId.url} target='_blank'
color='secondary'>{rowData.jobId.name}</Link>
},
{title: 'Job Name', field: 'jobName'},
{title: 'Submitted By', field: 'submittedBy'},
{title: 'Submitted Time', field: 'submittedTime'},
{title: 'Tenant', field: 'tenant'},
{title: 'Business', field: 'business'},
],
data: data
});

Is there other solution to use `R.applySpec` without inserting the unchanged keys value?

Is there other solution to use R.applySpec without inserting the the unchanged keys value?(without needs to type id and name keys in the example, because later the keys will be change dynamically). Thank you.
Here is my input data
const data = [
[
{ id: 'data1', name: 'it is data 1', itemId: 'item1' },
{ id: 'data1', name: 'it is data 1', itemId: 'item2' }
],
[
{ id: 'data2', name: 'it is data 2', itemId: 'item1' }
],
[
{ id: 'data3', name: 'it is data 3', itemId: 'item1' },
{ id: 'data3', name: 'it is data 3', itemId: 'item2' }
]
]
And the output
[
{
id: 'data1', // this one doesn't change
name: 'it is data 1', // this one doesn't change
itemId: [ 'item1', 'item2' ]
},
{
id: 'data2', // this one doesn't change
name: 'it is data 2', // this one doesn't change
itemId: [ 'item1' ]
},
{
id: 'data3', // this one doesn't change
name: 'it is data 3', // this one doesn't change
itemId: [ 'item1', 'item2' ]
}
]
The solution to get the output using Ramda
const result = R.map(
R.applySpec({
id: R.path([0, 'id']),
name: R.path([0, 'name']), // don't need to type id or name again
itemId: R.pluck('itemId')
})
)(data)
We could certainly write something in Ramda like this:
const convert = map (lift (mergeRight) (head, pipe (pluck ('itemId'), objOf('itemId'))))
const data = [[{id: 'data1', name: 'it is data 1', itemId: 'item1'}, {id: 'data1', name: 'it is data 1', itemId: 'item2'}], [{id: 'data2', name: 'it is data 2', itemId: 'item1'}], [{id: 'data3', name: 'it is data 3', itemId: 'item1'}, {id: 'data3', name: 'it is data 3', itemId: 'item2'}]]
console .log (convert (data))
.as-console-wrapper {min-height: 100% !important; top: 0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {map, lift, mergeRight, head, pipe, pluck, objOf} = R </script>
I'm not sure whether I find that more or less readable than a ES6/Ramda version, though:
const convert = map (
reduce ((a, {itemId, ...rest}) => ({...rest, itemId: [...(a .itemId || []), itemId]}), {})
)
or a plain ES6 version:
const convert = data => data .map (
ds => ds .reduce (
(a, {itemId, ...rest}) => ({...rest, itemId: [...(a .itemId || []), itemId]}),
{}
)
)
The question about applySpec is interesting. This function lets you build a new object out of the old one, but you have to entirely describe the new object. There is another function, evolve, which keeps intact all the properties of the input object, replacing only those specifically mentioned, by applying a function to their current value. But the input to the functions in evolve accepts only the current value, unlike applySpec which has access to the entire original object.
I could see some rationale for a function combining these behaviors. But I don't have a clear API in my head for how it should work. If you have some thoughts on this, and want to make a proposal, the Ramda team is always looking for suggestions.

react-absolute-grid, displayObject issue

I am trying to use this component: https://github.com/jrowny/react-absolute-grid.
The documentation says I should pass a displayObject which renders items.
So I created a displayObject, like the one in the docs which has this render method:
render: function() {
// Supposing your item shape is something like {name: 'foo'}
const { item, index, itemsLength } = this.props;
return <div>Item {index} of {itemsLength}: {item.name}</div>;
}
I passed it to the component like this:
<AbsoluteGrid
items={SampleData.screens}
displayObject={<DisplayObject/>}
onMove={onMoveDebounced}
dragEnabled={true}
responsive={true}
verticalMargin={42}
itemWidth={250}
itemHeight={250}
filteredProp={'name'}
/>
Where SampleData.screens is:
module.exports = {
screens: [
{'url': 'http://invisionapp.com/subsystems/do_ui_kit/assets/img/screens/original-1x/screen-1-1-login.jpg', 'name': 'login', 'sort': 1, 'key': 1},
{'url': 'http://invisionapp.com/subsystems/do_ui_kit/assets/img/screens/original-1x/screen-1-2-sign-up.jpg', 'name': 'signup', 'sort': 2, 'key': 2},
{'url': 'http://invisionapp.com/subsystems/do_ui_kit/assets/img/screens/original-1x/screen-1-3-walkthrough.jpg', 'name': 'walkthrough', 'sort': 3, 'key': 3}
]
};
When I open the page in the browser, I don't see the text from the displayObject.
How can I use the displayObject?
DisplayObject works good when is a function that return the render html, I try creating a different React.Component for it but got some issues
const items = [
{ key: "0", sort: 0, name: 'Test 1', filtered: false },
{ key: "1", sort: 1 ,name: 'Test 2', filtered: false },
{ key: "2",sort: 2, name: 'Test 3', filtered: false},
{ key: "3", sort: 3,name: 'Test 4', filtered: false }
]
function GridItem(props) {
const { item, index, itemsLength } = props;
return <div >
<span>{item.name}</span>
</div>;
}
const AbsoluteGrid = createAbsoluteGrid(GridItem);

Update Sequelize Array

I have looked everywhere, and I have not found an easy to understand method of updating a sequelize array, like this with a normal string:
db.User.update({name:req.body.name},{where : {username:req.body.username}}).then(function(user) {
res.json(user);
})
Sequelize doesn't support bulk updates using an array, see https://github.com/sequelize/sequelize/issues/4501
You have to implement a custom function.
Here is a basic example to give you an idea :
var promises = [];
userArray.forEach(function(user){
promises.push(db.User.update({name:user.name},{where : {username:user.username}});
});
Promise.all(promises).then(function(){
// success
}, function(err){
// error
});
Which I myself resolved as follows:
case 1: If you want to update multiple lines at the same value with different conditions
db.User.update({ name: 'name request' }, {
where: {
$or: [{ name: 'test 1', password: 'sasaccsa' }, {
name: "test 2"
}]
}
}).then(function(user) {
//query generate
// UPDATE `User` SET `name`='name request' WHERE ((`name` = 'test 1' AND `password` = 'sasaccsa') OR `name` = 'test 2')
res.json(user);
});
case 2: if you want to update multiple lines with different values for different types of reviews:
var arrayUpdate = [{
name: 'test 1',
id: 1
}, {
name: 'test 2',
id: 2
}, {
name: 'test 3',
id: 3
}];
sequelize.Promise.each(arrayUpdate, function(val, index) {
return db.User.update({
name: val.name
},{
where:{
id: val.id
}
}).then(function(user) {
}, function(err){
});
})
.then(function(updateAll){
//done update all
res.json(updateAll);
}, function(err){
});

Resources