The perplexing behavior of RxJS Observables with Mongo Cursors

Recently, I've been working on converting a mongo cursor into an observable using my own RxJS implementation. Despite finding numerous solutions online, I wanted to challenge myself by creating one from scratch.

I would greatly appreciate it if someone could help me understand why the code snippet below produces the output shown:

export function cursor$ <T> (cursor: Cursor<T>): Observable<T> {

    let counter = 1

    const d$ = (): Observable<T> => {
        counter++
        return from(cursor.hasNext())
            .pipe(
                tap(() => console.log(counter, 'before')),
                concatMap(x => x ? from( <Promise<T>>cursor.next() ) : empty()),
                tap(() => console.log(counter, 'between')),
                expand(() => d$()),
                tap(() => console.log(counter, 'after'))
            )
    }

    return d$()
}

As each item gets logged in the subscribe, 'done' is printed upon completion.

2 'before'
2 'between'
2 'after'
{ _id: 5bb5d47bbfa2d3ea077c37a6, name: 'Jeff' }
3 'before'
3 'between'
3 'after'
3 'after'
{ _id: 5bb5d483bfa2d3ea077c37a8, name: 'Jerald' }
5 'before'
5 'before'
5 'between'
5 'after'
5 'after'
{ _id: 5bb5d493bfa2d3ea077c37aa, name: 'Somebody' }
7 'between'
7 'after'
7 'after'
7 'after'
{ _id: 5bb5df8dbfa2d3ea077c39c8, name: 'Waddup' }
10 'before'
10 'before'
10 'before'
10 'before'
10 'before'
done

Answer №1

Successfully organized!

The issue was due to my use of calling expand within d$(), which was being invoked multiple times.

Here is the revised code using tap():

export function cursor$ <T> (cursor: Cursor<T>): Observable<T> {

    let counter = 0

    const next$ = () => from(cursor.hasNext())
        .pipe(
            tap(() => console.log(counter++, 'before')),
            concatMap(x => x ? from(<Promise<T>> cursor.next()) : empty()),
            tap(() => console.log(counter++, 'after')),
        )

    return next$().pipe(expand(() => next$()))
}

Desired output:

0 'before'
1 'after'
{ _id: 5bb5d47bbfa2d3ea077c37a6, name: 'Jeff' }
2 'before'
3 'after'
{ _id: 5bb5d483bfa2d3ea077c37a8, name: 'Jerald' }
4 'before'
5 'after'
{ _id: 5bb5d493bfa2d3ea077c37aa, name: 'Somebody' }
6 'before'
7 'after'
{ _id: 5bb5df8dbfa2d3ea077c39c8, name: 'Waddup' }
8 'before'
done

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error in three.js: Attempting to access the 'rotation' property of an undefined object

As I try to animate a cube in my scene, I keep encountering an error that reads: "TypeError: Cannot read property 'rotation' of undefined." function animate() { requestAnimationFrame( animate ); render(); } ...

php script within a literal .tpl file

Is there a way to perform a json_encode within a literal javascript block in the context of a Smarty template? {literal} <script> function openWin() { var O = {php} echo json_encode($obj);{/php}; // syntax error ...

Unlock the power of VueJS with advanced checkbox toggling for array data

I have encountered an issue while working with VueJS regarding the implementation of two features for a set of checkboxes. Initially, the checkboxes are generated dynamically. I am in need of a master 'toggle' checkbox that can toggle the stat ...

Ways to extract information immediately after using the .load method

Is there a way to instantly store data from .load in JavaScript? Whenever I use .load within a JavaScript function to retrieve content from the server and display it on the browser page, the content does not update immediately. It's only when the fu ...

inputting a pair of parameters into a function

While creating an action for react-redux, I encountered a problem when trying to pass two variables into the function - dispatch and hosts. Strangely, the variable host is being logged as a function instead of its actual value. This is my code: export fu ...

The jQuery hide and show functions lack precision and are too indiscriminate, requiring a more targeted approach

I am designing a unique contact card that captures a user's name and description from an <input> field and appends the input information into a <div> element. This is the flow I am aiming for... User inputs their first and last name alo ...

What is the reason that when we assign `'initial'` as the value for `display` property, it does not function as intended for list elements?

To toggle the visibility of elements, I have created a unique function that accepts an object and a boolean. Depending on the boolean value, either 'none' or 'initial' is assigned to the 'display' property of the specified obj ...

How come outerHTML retrieves <!-- --> comments?

I came across a jsfiddle link that showcases the collection of outerHTML for elements with a class='active'. Surprisingly, even when certain parts of the HTML are commented out like this: <!-- <div>'Some inner text'</d ...

Retrieve the scrollTop, scrollLeft properties, and other scroll-related data from an element using Selenium

When testing a Python/Django element that is scrolled using scrollTop, I am trying to retrieve the value of scrollTop. In JavaScript, I can access this value with: element.scrollTop I attempted to do this in Python using: element.get_attribute('sc ...

The error message "no match found" can only occur on the server-side when using jQuery version 1.x

Having an issue with this small section of code: $('.desc_container').each(function() { var fulltext = $(this).text(); if(fulltext.length > 50) { var myRegexp = /^(.{47}\w*\W)(.*?)$/g; var match = myRegexp.exec(f ...

Issue: Unhandled promise rejection: BraintreeError: The 'authorization' parameter is mandatory for creating a client

I'm currently working on integrating Braintree using Angular with asp.net core. However, I've encountered an issue that I can't seem to solve. I'm following this article. The version of Angular I'm using is 14, and I have replicate ...

The Bootstrap tooltip effectively fades away after displaying text, but it is not positioned correctly above the icon

Having some issues with my tooltip functionality. It seems to display the text on the left side and fades away upon mouseover, but it doesn't show up in a proper tooltip box over the icon as expected. I suspect that there might be a conflict between j ...

Count Scroller - Finding a Solution for _.debounce

Issue with Counter I have a counter that should increase or decrease by one each time the user scrolls up or down. The problem I'm facing is that my counter $('html').on('mousewheel', function (e) { var delta = e.originalEve ...

Conceal the <p> element when the user interacts with the internal href

After creating this document using JQuery, whenever the user clicks on different internal links, a div with id = "change" is loaded which effectively "erases" the content. My challenge at the moment is that while images are successfully deleted, text rema ...

How can you retrieve an array of multiple property values from a collection of dynamic objects?

I am currently working with a dynamic JavaScript object array that has varying structures. For example: var someJsonArray = [ {point: 100, level: 3}, {point: 100, level: 3}, {point: 300, level: 6} ]; At times, it may have a different combination lik ...

Conceal the block quotes while substituting with a newline

My HTML page contains numerous comments enclosed in blockquotes. I attempted to implement a feature that allows users to hide all the comments with just one click by using the following JavaScript code: const blockQuotes = document.getElementsByTagName(& ...

Leveraging callback functions for dynamically updating a JSON structure

Recently, I've been working on a db_functions.js file that includes several functions designed to interact with a database. Here's an excerpt from the script: function getUsers(client, fn){ //var directors = {}; client.keys('*' ...

Why isn't my file being recognized post-multer middleware?

I am currently facing an issue with uploading a filename and a post (similar to 9GAG style) to my MySQL database, and storing the file in my project folder. The front end is able to retrieve the file without any problems (verified through console.log), but ...

How can you conceal the navigation and footer components on a 404 page using Next.js?

import Footer from "./Footer"; import Navigation from "./Navigation"; import { useRouter } from "next/router"; function CustomLayout({ children }) { const router = useRouter(); return ( <> {router.pathname ...

JavaScript's data.map function cannot be found

I've been developing a full stack application using Vue.Js, NodeJS, ExpressJS, and MongoDB. In my frontend code, I have a PostService.js class that manages HTTP requests to the API. However, I encountered an issue while trying to map the response data ...