0

I created a function which makes some text flowing:

   private createFlowingText(message: string): Observable<string> {
      const intrvl = interval(180);
      const text = from(message);

      const flowTxt = zip(intrvl, text).pipe(
         map(([_, letter]) => letter),
         scan((acc, letter) => {
            const withoutDots = acc.endsWith("...") ? acc.slice(0, -3) : acc;
            return `${withoutDots}${letter}...`;
         }, ""),
         repeat(3)
      );
      const blinkCursor = interval(400).pipe(
         map((i) => (i % 2 == 0 ? "|" : "")),
         map((tube) => `${message}...${tube}`)
      );

      return concat(flowTxt, blinkCursor);
   }

I introduced a separate blinkCursor observable to simulate blinking cursor when text flown three times. And I had to pass a message value to it. I wonder how can I improve this code without introducing this second observable. So, when the first is finished I switch to the second one and use a single set of operators (passing the resulting text from the first one to the second down the pipeline).

Here's the stackblitz - https://stackblitz.com/edit/stackblitz-starters-jbpdgtzb?file=src%2Fmain.ts

1 Answer 1

0

Asked AI to help me and it fixed it with explanations:

private createFlowingText(message: string): Observable<string> {
      
      // fixed with Gemini

      const intrvl = interval(180);
      const textObservable = from(message);

      const flowTxt = zip(intrvl, textObservable).pipe(
         map(([_, letter]) => letter),
         scan((acc, letter) => {
            const withoutDots = acc.endsWith("...") ? acc.slice(0, -3) : acc;
            return `${withoutDots}${letter}...`;
         }, ""),
         repeat(2),
         // ShareReplay ensures that when blinkCursor subscribes, it gets the last emitted value
         // from flowTxt without re-executing the entire flowTxt observable.
         // bufferSize: 1 means it will replay the last 1 value.
         // refCount: true means it will automatically connect/disconnect to its source
         // when the number of subscribers goes from 0 to 1 or 1 to 0.
         shareReplay({ bufferSize: 1, refCount: true })
      );

      const blinkingTextObservable = flowTxt.pipe(
         last(), // Get the very last emitted value from flowTxt
         concatMap((finalText) => {
            // Now use this final text for the blinking cursor
            return interval(400).pipe(
               map((i) => (i % 2 == 0 ? "|" : "")),
               map((tube) => `${finalText}${tube}`) // Use the finalText here
            );
         })
      );

      // Concat flowTxt and then the blinkingTextObservable
      return concat(flowTxt, blinkingTextObservable).pipe(takeUntil(this.isLoadingSet$));
   }

Nice.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.