The CycleDOM conundrum with conditional rendering

Having a problem with conditional rendering. Check out my flawless view:

function todoItem(todo) {
  return li('.list-item',[
    todo.editing ? input('.todo-edit', {type: 'text', value: todo.text, autofocus: true, attributes: { 'data-id': todo.id }}) : '',
    !todo.editing ? span(`.todo ${todo.completed ? '.completed' : ''}`, { attributes: { 'data-id': todo.id }}, todo.text) : '',
    button('.remove-todo', {type: 'button', value: todo.id}, 'remove'),
    todo.completed ? button('.unmark-todo', {type: 'button', value: todo.id}, 'unmark') : '',
    !todo.completed ? button('.mark-todo', {type: 'button', value: todo.id}, 'mark as done') : ''
  ]);

const view = (state$) => {
  return state$.map(todos =>
    div([
      input('.todo-input', {type: 'text', placeholder: 'Todo', value: ''}),
      ul(todos.items.map(todo => todoItem(todo))),
      footer(todos)
    ])
  );
};

The issue arises when trying to convert the conditional buttons to an if-else statement instead of two separate conditions:

todo.completed ?
  button('.unmark-todo', {type: 'button', value: todo.id}, 'unmark') :
  button('.mark-todo', {type: 'button', value: todo.id}, 'mark as done')

It seems like it switches between "unmark" and "mark" repeatedly (confirmed with console logs). The classes .mark and .unmark are correctly assigned, so that should not be the problem...

Is this an actual error or am I overlooking something?

Answer №1

This issue with the dom driver bug has been brought to your attention: https://github.com/cyclejs/core/issues/228

The issue arises from both toggled elements being buttons. When transitioning from todo.completed to !todo.completed, virtual-dom simply updates the existing button's class and label rather than creating a new button in order to minimize changes to the DOM structure.

This update occurs synchronously while the click event is still being processed. Once the class name is modified, the event moves on to the next listener which now also matches the updated class and triggers the event again. This subsequent listener is responsible for unmarking the task once more.

A temporary solution would be to assign a key attribute to both buttons to prompt virtual-dom to recreate the buttons. However, it is important to note that this behavior stems from a bug within the dom driver itself.

todo.completed ?
  button('.unmark-todo', {key: 'unmark', type: 'button', value: todo.id}, 'unmark') : 
  button('.mark-todo', {key: 'mark', type: 'button', value: todo.id}, 'mark as 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 Message: Error Code 2. I am encountering an issue with the bot expecting either undefined or null and receiving a string primitive instead. Any

As I delved into creating a music bot with support for slash commands, everything seemed to be going smoothly when embedding a URL to a single song. However, the trouble began when attempting to include a link to a playlist, resulting in two perplexing err ...

Discrepancy in post results

I am currently working on integrating two scripts - a Prestashop DHL label creator and our company's internal sales application. The goal is to streamline the process of generating DHL labels directly from our sales application without the need to acc ...

Challenges encountered when attempting to send an array in res.json with the MERN stack

I am facing a challenge while trying to make two separate model calls using the MERN stack. The issue arises when I try to send an array in res.json; extracting the data seems to be problematic. On examining the console log: {data: "[]", status: ...

Nested for loop in JavaScript causing the display of only the final value of the iterating object

When constructing a JSON array object using two different arrays, I noticed that the value of the last iterated value is being assigned to every element in the array. Specifically, for the serial number element, only the last iterated value is being displa ...

Incorporating a dynamic fill effect into an SVG pie chart

I am looking to animate a pie chart with a variable value that is unknown upon loading. Assuming I fetch the value promptly and convert it into a rounded percentage : var percentage = Math.round(sum * 100 / total); Next, I place this value here : <di ...

Could one achieve the task without the presence of a function?

When I execute the below code: let app = express() in the console, it outputs: { [EventEmitter: app] _events: { mount: [Function: onmount] }, _eventsCount: 1, _maxListeners: undefined, setMaxListeners: [Function: setMaxListeners], getMaxList ...

Encountering an issue with resolving 'create-react-class'

I have some files with hobbies listed in Data.js. I am attempting to add these hobbies and display them in a list format within my App.js file. However, I keep encountering an error stating that the create-react-class module cannot be found. Does anyone k ...

The console is not displaying the data from the useForm

I am working on a project to create a Gmail clone. I have implemented the useForm library for data validation. However, when I input data into the form and try to print it to the console, nothing is being displayed. const onSubmit = (data) => { ...

AngularJS implemented a header authorization feature

I've been attempting to include an authorization header in my requests, but I'm facing some issues. Here is the code I am using: var config = {headers: { 'Authorization': token } }; return $http.get('http://localhost:3000/api ...

Encountering issues with reading undefined properties while working with react-chartjs-2 and chart js

Having trouble with react chartjs errors? Visit the link for more details https://i.stack.imgur.com/lI2EP.png The versions I'm using are ^3.5.0 for chart.js and ^4.0.1 for react-chartjs-2 Tried downgrading to version 2 but it didn't solve the ...

Tips for utilizing a switch statement

I'm a beginner in JavaScript and recently learned about the switch statement. I have an exercise where I need to convert numbers 1-10 into words like "one", "two", "three"... This is what I have tried so far: function sayNum(){ let numberArray = [ ...

I am experiencing difficulty typing continuously into the input box in reactJS

In one of my components, I have the capability to add and delete input fields multiple times. <> <form onSubmit={optimizeHandler}> <div className="filter-container"> {conditions.map((condition, index) => ...

What is the best way to create a floating navigation bar that appears when I tap on an icon?

As a beginner in the realm of React, I recently explored a tutorial on creating a navigation bar. Following the guidance, I successfully implemented a sidebar-style navbar that appears when the menu icon is clicked for smaller screen sizes. To hide it, I u ...

What is the best way to create a reusable component for a Material-UI Snackbar?

Having trouble getting my Alert component to display a message that says "Successfully submitted" in the parent component. The message doesn't seem to be showing up. AlertComponent import React, { useState } from "react"; import { Snackbar, Alert } f ...

Using Driver Wait Until Text in Selenium involves waiting for a specific text to appear on a

I'm currently experimenting with the driver wait function using this specific wait condition. My goal is to verify that the text displayed on a button is exactly "Sign Up". Below is the code snippet I am working with: driver.wait(until.elementTextIs( ...

Injecting sinon js into an application within an iFrame: a step-by-step guide

I am looking to implement ajax requests testing in my application. The application is running within an iframe, and my goal is to have the iframe's wrapper page test the application using sinon (which will send the response). I attempted to include ...

Update the CSS styles using jQuery

I am looking to update the content within a CSS tag using jQuery. In this instance, I need to change "My content" to "New Content". Here is the CSS code I have: a.appari:focus:after{ background: #333; background: rgba(0,0,0,.8); border-radius: 5px ...

"Utilizing jQuery Mobile's Pagebeforeshow event with the advanced functionality of longlist

Currently, I am utilizing JQuery mobile version 1.0.1. To set up a page, the following code is utilized: <div data-role="page" id="homecomments"> <div data-role="header"> <h1>Comments</h1> <a href='#home&apo ...

Are you experiencing issues with your Ajax request?

I've been struggling to retrieve json data from an API. Despite my efforts, the GET request seems to be executing successfully and returning the correct data when I check the Net tab in Firebug. Can anyone offer advice on what could be going wrong or ...

Youngster listens for guardian's occurrence in Angular 2

While the Angular documentation covers how to listen for child events from parents, my situation is actually the opposite. In my application, I have an 'admin.component' that serves as the layout view for the admin page, including elements such a ...