Is there an equivalent to the RxJS v4 case operator in RxJS v5? - rxjs5

I found the docs for the old case operator here: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/case.md
It is not listed in the migration guide:
https://github.com/ReactiveX/rxjs/blob/stable/MIGRATION.md
Is there some combination of supported operators that would provide the same functionality?

RxJS v4 Rx.Observable.case(selector, sources, [elseSource|scheduler]), example given is
var sources = {
'foo': Rx.Observable.return(42),
'bar': Rx.Observable.return(56)
};
var defaultSource = Rx.Observable.empty();
var source = Rx.Observable.case(
function () {
return 'foo';
},
sources,
defaultSource);
I guess you could could do this in RxJS v5
var sources = {
'foo': Rx.Observable.return(42),
'bar': Rx.Observable.return(56)
};
var defaultSource = Rx.Observable.empty();
var source = Rx.Observable.of('foo')
.mergeMap(srcName => {
const src = sources[srcName];
return src || defaultSource;
})
Would be interested to know where you are using / want to use this operator.

Related

Can nested loops be used in Cypress?

I would like to know if Cypress supports nested loops?
In my case, I have a table where I need to iterate over each row (row is represented by the "data-automationid="DetailsRowFields"") and then over each cell.
Although I attempted to create a function that would extract it, I am unsure if it can be done.
export function getCellData() : Promise<Map<string, string>> {
return new Cypress.Promise((resolve) => {
const cellMap = new Map<string, string>();
cy.get('div[data-automationid="DetailsRowFields"]')
.each((rowElement) => {
rowElement.children()
.each((child) => {
const ariaIndex = child.attr('aria-colindex');
const cellData = child.text();
cellMap.set(ariaIndex, cellData);
});
})
.then(() => resolve(cellMap));
});
}
That won't quite work as you expect, you will only get the last row data.
The Map key should include the row index.
Also, rowElement is a jQuery object. While jQuery does have methods for .children() and .each(), the calling pattern is different to the equivalent Cypress .each().
I recommend wrapping the rowElement.
const cellMap = new Map<string, string>();
cy.get('div[data-automationid="DetailsRowFields"]')
.each((rowElement, rowIndex) => {
cy.wrap(rowElement)
.children()
.each((child) => {
const ariaIndex = child.attr('aria-colindex');
const cellData = child.text();
const mapKey = `${rowIndex}:${ariaIndex}`
cellMap.set(mapKey, cellData);
})
})

Can we use customHooks into redux Saga function

Following custom hooks as state selector and using that within "functional View" component.
Now, I need to use that in redux Saga function. Can we use that into Saga function or I have to use some other approach instead of using custom hooks into Saga function ?
export function useSelectAllEntries()
{
return useSelector(
({allEntries=[]}) =>[...allEntries],shallowEqual
);
}
export function useSelectFilteredByMakeEntries()
{
const selectAll = useSelectAllEntries();
return selectAll.filter(...);
}
export function useSelectFilteredByCreatorEntries()
{
const selectAll = useSelectAllEntries();
return selectAll.filter(...);
}
Instead of defining these as custom hooks, define them as selectors instead. Redux selectors may be freely shared between multiple different use-cases.
export const allEntriesSelector = ({ allEntries = [] }) => allEntries;
export const allEntriesFilteredByMakeEntriesSelector = state =>
allEntriesSelector(state).filter(...);
export const allEntriesFilteredByCreatorEntriesSelector = state =>
allEntriesSelector(state).filter(...);
Then, when you want to use them in a function component, just call useSelector:
function MyComponent() {
const entries = useSelector(allEntriesSelector);
const filteredByMake = useSelector(allEntriesFilteredByMakeEntriesSelector);
const filteredByCreator = useSelector(allEntriesFilteredByCreatorEntriesSelector);
return (...);
}
and when you want to use them within a saga:
import { select } from 'redux-saga/effects';
function* mySaga() {
const entries = yield select(allEntriesSelector);
const filteredByMake = yield select(allEntriesFilteredByMakeEntriesSelector);
const filteredByCreator = yield select(allEntriesFilteredByCreatorEntriesSelector);
}

Using cypress to read the dom and create an array data structure for each of the rows

Please take a look this image. Want to know how could I do this using cypress?
You can use something like this depending on what exactly are you looking for:
cy.get('table')
.find('tbody tr')
.then(trs => {
const content = [];
Cypress.$(trs).each((_, tr) => {
const row = [];
const tds = Cypress.$(tr).find('td');
Cypress.$(tds).each((_, td) => {
const text = Cypress.$(td)
.contents()
.last()
.text();
row.push(text);
});
content.push(row);
});
console.log(content);
});

Unit testing redux-saga select

I have a simple saga of this form:
const getAccountDetails = function * () {
const { url } = yield select(state => state.appConfig)
const accountDetails = yield call(apiFetchAccountDetails, url)
}
I'm trying to write a unit test:
describe('getAccountDetails', () => {
const iterator = getAccountDetails()
it("should yield an Effect 'select(state=> state.appConfig)'", () => {
const effect = iterator.next().value
const expected = select(state => state.appConfig)
expect(effect).to.deep.eql(expected)
})
This test fails. Although effect and expected are very similar, they are not identical.
At least one of the differences is buried in payload.selector.scopes, where the yielded effect and expected are as follows:
As the scopes of these two will always be different, how can these tests ever be made to work?
eta: this pattern is adapted from the example linked to from the redux-saga docs
Cracked it after finding this issue from way back.
The fix is to create a named function to do the select and export it from the module where the saga under test lives, and then use this same function in tests. All is well.
export const selectAppConfig = state => state.appConfig
const getAccountDetails = function * () {
const { url } = yield select(selectAppConfig)
const accountDetails = yield call(apiFetchAccountDetails, url)
}
import {selectAppConfig} from './sagaToTest'
describe('getAccountDetails', () => {
const iterator = getAccountDetails()
it("should yield an Effect 'select(state=> state.appConfig)'", () => {
const effect = iterator.next().value
const expected = select(selectAppConfig)
expect(effect).to.deep.eql(expected)
})

Get random element from Graphcool?

Is it possible to return a random graphql element from a Graphcool backend? If so, how could this be done?
Alternatively, any tips on howto create custom queries for Graphcool backends?
The best way to do this is by using the API Gateway pattern.
The idea of that approach is to put a gateway server on top of Graphcool's CRUD API and thus customize the API. With this approach, you'd write an additional resolver function that retrieves the random element for you:
const extendTypeDefs = `
extend type Query {
randomItem: Item
}
`
const mergedSchemas = mergeSchemas({
schemas: [graphcoolSchema, extendTypeDefs],
resolvers: mergeInfo => ({
Query: {
randomItem: {
resolve: () => {
return request(endpoint, allItemsQuery).then(data => {
const { count } = data._allItemsMeta
const randomIndex = Math.floor((Math.random() * (count-1)) + 0)
const { id } = data.allItems[randomIndex]
return request(endpoint, singleItemQuery, { id }).then(data => data.Item)
})
},
}
},
}),
})
I created a full example of this here. Let me know if you have any additional questions :)

Resources