I am facing some problems removing an items from an array from every element within a map in my Redux state.
Using the following structure
entities: {
brands: (Map) {
first: {
...props,
strategists: [
'1', '2'
]
},
second: {
...props,
strategists: [
'1', '2'
]
}, ..
}
}
This is the best I could do:
const newBrands = state
.get('brands')
.map(brand => brand.updateIn(['strategists'], strategists => strategists.filter(s => s !== id)))
return state.set(['brands'], newBrands)
I doesn't add up tho and I coudn't really find it online either.
Thanks
I had not used Immutable.js before, but I played around with your code example and everything seems to work as expected up until the last line, where you're setting state using state.set(['brands'], newBrands) instead of state.set('brands', newBrands); Could that have been the issue? Otherwise the only change is that I assumed that the first and second should also be Maps, so if you got an error before then maybe that was also part of the problem.
I included the code just in case:
const state = Immutable.Map({});
const original = Immutable.Map({
first: Immutable.Map({
someProp: 'someValue1',
strategists: [
'1', '2', '3'
]
}),
second: Immutable.Map({
someProp: 'someValue2',
strategists: [
'1', '2', '3'
]
})
});
const id ='2';
const brands = original
.map(brand =>
brand.updateIn(['strategists'], strategists =>
strategists.filter(s => s !== id)
)
);
const newState = state.set('brands', brands);
console.log(
newState.get('brands')
.toString()
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
Related
I need to take 2 lists of text values on page to use each of them in different cheking.
I do it by xpath
cy.xpath('//tbody/tr[position()<10]/td[6]/span').then(items => {
cy.wrap(items).as('multipleList')
})
cy.xpath('//tbody/tr[position()<21][position()>15]/td[6]/span').then(items => {
cy.wrap(items).as('commaList')
})
cy.get('#multipleList').each((qwer, index) => {..........})
cy.get('#commaList').each((qwer, index) => {..........})
But after using the first list (#multipleList), it shows error that the second list (#commaList) is empty.
If I swap them, then #commaList is being executed OK, but #multipleList shows the same error.
Try a combined selection and iteration only once
cy.xpath('//tbody/tr').as('list')
cy.get('#list').each(($rows, rowIndex) => {
if (rowIndex < 9) {
const $span = $rows[index].find('td:eq(6) span')
...
}
if (rowIndex > 14 && rowIndex < 20) {
const $span = $rows[index].find('td:eq(6) span')
...
}
})
With the test as you've shown, it's not possible.
If you have an error it's the processing in .each() causing page changes (2nd list becomes invalid).
Try to reorder the commands
cy.xpath('//tbody/tr[position()<10]/td[6]/span').as('multipleList')
cy.get('#multipleList').each((qwer, index) => {..........})
cy.xpath('//tbody/tr[position()<21][position()>15]/td[6]/span').as('commaList')
cy.get('#commaList').each((qwer, index) => {..........})
im building my request data as an array structure and want to use the symfony XmlEncoder to encode my Array to XML.
so i guess i got the fundamental part right, it looks like that for example:
$request_object = [
"acc-id" => $all_credentials,
"req-id" => $request_guid,
"tran-type" => "spec-url"
];
the syntax im looking for encodes in the following format, with attribute and value:
<amount currency="EUR">1.99</amount>
i have the possiblity to use the # sign on an array key, but how to also fit in the value?
$request_object = [
"acc-id" => $all_credentials,
"req-id" => $request_guid,
"tran-type" => "spec-url"
"am" => ["#attr"=>"attrval"]
];
this should be
<am attr="attrval"/>
but how to write it that i can also set the value? like:
<am attr="attrval">VALUE</am>
help is much appreciated
Use '#' as the index for the scalar value.
I found it by looking through the tests for the encoder.
#src:https://github.com/symfony/serializer/blob/master/Tests/Encoder/XmlEncoderTest.php
#line: 196
public function testEncodeScalarRootAttributes()
{
$array = [
'#' => 'Paul',
'#eye-color' => 'brown',
];
$expected = '<?xml version="1.0"?>'."\n".
'<response eye-color="brown">Paul</response>'."\n";
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
}
...
#line: 234
public function testEncodeScalarWithAttribute()
{
$array = [
'person' => ['#eye-color' => 'brown', '#' => 'Peter'],
];
$expected = '<?xml version="1.0"?>'."\n".
'<response><person eye-color="brown">Peter</person></response>'."\n";
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
}
The goal is simple: to join two firestore queries utilizing rxjs, rxfire, and the rnfirebase react native library.
I've read multiple tutorials 1, 2 on joining queries, but they all fail with different errors.
//Simple test for collectionData
import { collectionData } from 'rxfire/firestore';
this.myQuery = this.props.docRef.collection(`messages`).where('read', 'array-contains', this.props.me.uid)
collectionData(this.myQuery, 'id').subscribe(docs => console.log(docs))
//Fails with error: this._next is not a function.
Alternatively,
this.publicQuery = this.props.docRef.collection('messages').where('public', '==', true)
this.myQuery = this.props.docRef.collection(`messages`).where('read', 'array-contains', this.props.me.uid)
const myQuery$ = new Rx.Subject();
const publicQuery$ = new Rx.Subject();
this.myQuery.onSnapshot((querySnapshot) => {
myQuery$.next(querySnapshot.docs.map(d => d.data() ));
});
this.publicQuery.onSnapshot((querySnapshot) => {
publicQuery$.next(querySnapshot.docs.map(d => d.data() ));
});
const orQuery$ = combineLatest(this.myQuery, this.publicQuery).switchMap((docs) => {
var [one, two] = docs;
var combined = one.concat(two);
return Rx.Observable.of(combined);
})
orQuery$.subscribe((result) => {
console.log('>>>> ', result)
})
//TypeError: undefined is not a function (near ...switchMap)
How can I successfully join two firestore queries (OR)?
You're already very close to the solution. Let's go through the issues step-by-step.
First, it's not necessary to create a Subject just to transform your result from onSnapshot. Instead of this:
this.myQuery.onSnapshot((querySnapshot) => {
myQuery$.next(querySnapshot.docs.map(d => d.data()))
});
We can achieve the same using 'pipeable transformation operators':
const myQuery$ = this.myQuery.onSnapshot.pipe(
map(querySnapshot => querySnapshot.docs.map(d => d.data()))
);
The same goes for the other query:
const publicQuery$ = this.publicQuery.onSnapshot.pipe(
map(querySnapshot => querySnapshot.docs.map(d => d.data())
);
Second, to join those two queries, combineLatest is indeed the correct creation function.
However, your error might result from you using a newer RxJS version, that doesn't support 'fluent' operators (officially called "patch operators") anymore. They have been replaced by 'pipeable operators' from RxJS 6 onwards. As an example, myObs$.map(...) has become myObs$.pipe(map(...)). The tutorials probably use an older version of RxJS where the first is still possible.
Also, it shouldn't be necessary to use switchMap if the inner Observable is just an of operator. It is sufficient in this case to use the map operator, which will behave equally.
Using the new RxJS 6+ syntax together with map, the combination will look like this:
const orQuery$ = combineLatest(myQuery$, publicQuery$).pipe(
map(([one, two]) => one.concat(two))
)
The rest of your code should be correct.
Side Note: Keep in mind that the equivalent of your code in SQL is UNION (not JOIN). In order to JOIN programatically, you'd need to combine each object of result set A with each object of result set B and create a joined object for each pair. Such a function for a keyless OUTER JOIN would look like this (placed in your map pipe):
one.map(a =>
two.map(b => Object.assign({}, a, b)))
.reduce((p, c) => p.concat(c), [])
If you want to have a UNION with no duplicate objects, concat only those items from two that have no matching primary key in list one. This would be your mapping function:
one.concat(two.filter(twoItem => !one.some(oneItem => oneItem.id == twoItem.id)))
DEMO: A complete, working demo with the above code and a simulated FireStore can be found here:
https://stackblitz.com/edit/rxjs-mefynu?devtoolsheight=60
Hello Now i have a problem. I want to insert data to array of objects using for loop
fields:{
type:[Object],
label:"Fields",
optional:true
},
"fields.$.category":{
type:String,
label: "Category"
},
"fields.$.sub":{
type:String,
label:"Sub Category",
},
And using savaData.js in server i tried
// ServiceProviders.update({
// '_id':"GmkGSXjyNFshomdCu"},
// {
// '$set': {'fields':{
// '$.category':categorydata,
// '$.sub':subdata
// }}
// },function(error,result){console.log(error);console.log(x+y);});
and
ServiceProviders.update(
{'_id': 'JN4mRPfJZqBadZtPY' },
{'$set': {'fields.0.category': categorydata,'fields.0.sub':subdata}},
true );
then
var x = "fields."+i+".category";
var y = "fields."+i+".sub";
x=x.toString();
y=y.toString();
ServiceProviders.update(
{'_id': 'JN4mRPfJZqBadZtPY' },
{'$set': {x: categorydata,y:subdata}},
true );
I got Different errors every time could you please help me in this issue
Currently, $ Does not work on Meteor js.
So you have to create a fields object on either server side or client side:
var fieldsData = []
for (var i = 0; i < categorydata.length || i < subdata.length ; i++ ){
fieldsData.push({
category : ( categorydata[i] ? categorydata[i] : '' ),
sub : ( subdata[i] ? subdata[i] : '' )
})
}
ServiceProviders.update(
{'_id': 'JN4mRPfJZqBadZtPY' },
{'$set': {fields : fieldsData}},
true );
Please make sure for either every filds data have cat and subcat value or make cat and subcat cat optional true.
Trying to find the cleanest way to reduce a Map in Dart. Looking for something akin to JavaScript's Array.prototype.filter()
Any suggestions? The following method leaves a lot to be desired:
Map ingredients = {
'flour': '250g',
'butter': '50g',
'egg': 1,
'water': '0.2l'
};
final flour = new Map.fromIterable(
ingredients.keys.where((k) => ingredients[k] == '250g'),
value: (k) => ingredients[k]
);
print(flour); // {flour: 250g}
There is no built in support for Pairs in the core library. However if you find yourself doing this type of thing often, you could write a utility library. For example:
library pairs;
class Pair<K,V> {
Pair(this.k, this.v)
final K k;
final V v;
String toString() => '($k, $v)';
}
Iterable<Pair> asPairs(Map map) => map.keys.map((k) => new Pair(k, map[k]));
Map fromPairs(Iterable<Pair> pairs) => new Map.fromIterables(
pairs.map((p) => p.k),
pairs.map((p) => p.v));
Then you can use it like this:
import 'src/pairs.dart';
Map flour = fromPairs(asPairs(ingredients).where((p) => p.v == '250g'));
print(flour); // {flour: 250g}
Perhaps this is something that could be contributed to the quiver package, a set of non-core utilities.
There is now a map property to get all Map entries.
So you can do:
void main() {
Map ingredients = {
'flour': '250g',
'butter': '50g',
'egg': 1,
'water': '0.2l'
};
var flour = Map.fromEntries(
ingredients
.entries
.where((e) => e.value == '250g'),
);
print(flour);
}
You would play with e.key if you were interested in the key's value.
Concerning a reduce method, you could use the fold method on the filtered entries List.