Socket input help

Hi all! Could someone help me with my code?

Let me explain a bit.

I have a large table (I have the data stored in a map) and data arrives through the socket very often.


I have a logic for when a new data arrives, I verify if the new value is greater or less than the previous one
and thus assign a blink animation in my table. All that logic I do in a map called “mapOfColors”

My problem is that when, for example, if a new value arrives that is greater than the old one (the green animation is assigned) and then it arrives
another value with the same case that it is greater than the previous one (green animation), this second animation is not reflected.
I try to reset the property in my “mapOfColors” but the animation does not run again.

Does anyone know any way to create this blinking system or how to improve my logic?

Regards!

    <template>
      <div>
        <el-table
            :data="displayData"
            :span-method="objectSpanMethod"
            style="width: 100%; border-radius: 10px 10px 0px 0px"
                :header-cell-style="$colorMode.preference === 'dark' ? tableHeaderColorDark : tableHeaderColorLight"

          >
            <el-table-column label="Mid Price" align="right" >
                <template slot-scope="slot">
                <span :class="[mapOfColors.get(slot.row.exchange.toLowerCase() + slot.row.market)['midPrice']]"
                  >{{ formatCurrencyFiat(slot.row.midPrice) }}</span
                >
              </template>
            </el-table-column>
            <el-table-column label="Spread" align="right" >
                <template slot-scope="slot">
                <span :class="[mapOfColors.get(slot.row.exchange.toLowerCase() + slot.row.market)['bidAskSpread']]"
                  >{{ formatCurrencyFiat(slot.row.bidAskSpread) }}</span
                >
              </template>
            </el-table-column>
            <el-table-column label="Spread %" align="right" >
                <template slot-scope="slot">
                <span :class="[mapOfColors.get(slot.row.exchange.toLowerCase() + slot.row.market)['bidAskQuotedSpread']]"
                  >{{ formatPercent(slot.row.bidAskQuotedSpread) }}</span
                >
              </template>
            </el-table-column>
            <el-table-column label="Volume" align="right">
                <template slot-scope="slot">
                <span :class="[mapOfColors.get(slot.row.exchange.toLowerCase() + slot.row.market)['volume']]"
                  >{{ formatCurrencyFiat(slot.row.volume) }}</span
                >
              </template>
            </el-table-column>
          </el-table>
      </div>
    </template>

    <script>
    import Vue from 'vue';
    import { getUriImg } from '@/supports/global'
    import { tableHeaderColorLight, tableHeaderColorDark } from '@/supports/global'
    import { formatCurrencyFiat, formatPercent } from '@/supports/numbers'
    import { mapGetters } from 'vuex'

    export default Vue.extend({
      components: {SelectCurrencyApiSync, SelectExchangeApiSync},
      props: [],
      sockets:{
        'market-data-ticker-all'(data){
            let key = data.exchange.toLowerCase()+data.market
            let getProp = this.typePropChanged.get(data.type)
            this.mapOfColors.get(key)[getProp] = 'text-current'
                if(this.tickersMap.get(key)[getProp] < data.value){
                  this.mapOfColors.get(key)[getProp] = getProp === 'BEST_ASK' ?  'transition-color-red-ticker' : 'transition-color-green-ticker'
                }else{
                  this.mapOfColors.get(key)[getProp] = getProp === 'BEST_ASK' ?  'transition-color-green-ticker' : 'transition-color-red-ticker'
                }
              this.tickersMap.get(key)[getProp] = data.value
            }
      },
      data (){  
        return {
            exchanges: [],
            exchangesList: null,
            tickersList: [],
            tickersMapChangeTracker: 1,
            tickersMap: new Map(),
            tickersCurrencyList: [],
            typePropChanged: new Map([ 
              ['BEST_BID', 'bidPrice'],
              ['BEST_ASK', 'askPrice'],
              ['LAST', 'lastPrice'],
              ['OPEN', 'open'],
              ['CLOSE', 'close'],
              ['HIGH', 'high'],
              ['LOW', 'low'],
              ['VOLUME', 'volume'],
              ['MID_PRICE', 'midPrice'],
              ['BID_ASK_SPREAD', 'bidAskSpread'],
              ['BID_ASK_QUOTED_SPREAD', 'bidAskQuotedSpread']
             ]
            ),
            mapOfColors: new Map(),
        } 
        },
      methods: {
        getUriImg,
        tableHeaderColorLight,
        tableHeaderColorDark,
        formatCurrencyFiat,
        formatPercent,
        addToMap(key, item) {
            this.tickersMap.set(key, item);
            this.tickersMapChangeTracker += 1;
        },
        joinRoom() {
            this.$socket.client.emit('join', {
              room: 'market-data-ticker-all',
              token: `${this.userToken}`,
            })
          },
        leaveRoom() {
            this.$socket.client.emit('leave', {
              room:  'market-data-ticker-all',
              token: `${this.userToken}`,
            })
          },
        async getExchangesList() {
          await this.$accounting
            .$get(`/exchange/getAll`)
            .then((response) => {
              this.exchangesList = response.exchanges.filter(item => item.enabled === true)
              this.getTickers()
            })
            .catch((error) => {
              console.log({ error })
            })
        },
        setMapOfColors(){
          this.tickersCurrencyList.forEach(item => {
            let key = item.exchange.toLowerCase()+item.market
            this.mapOfColors.set(key, {
                volume: '',
                lastPrice:  '',
                askPrice: '',
                bidPrice: '',
                open: '',
                close: '',
                high: '',
                volume: '',
                bidAskQuotedSpread: '',
                bidAskSpread: '',
                midPrice: '',
            })
            this.addToMap(key, item)
            }
          )
          this.joinRoom()
        },
        async getTickers(){
            await this.exchangesList.forEach(item => {
                 this.$marketdata
                .$get(`ticker/getAll`, {
                    params:{
                        exchange: item.exchangeId,
                    }
                })
                .then((response) => {
                  this.tickersList = [...this.tickersList, ...response.ticker]
                  this.setCurrencyTickers()
                })
                .catch((error) => {
                  console.log({ error })
                })
            })
        },
        setCurrencyTickers(){
          this.tickersCurrencyList = this.tickersList.map(item => ({...item, currency: item.market.split('-')[0]}))
          this.setMapOfColors()
        },
      },
      computed:{
          ...mapGetters('auth', ['userToken']),
        tickersMapAsList() { 
          return this.tickersMapChangeTracker && Array.from(this.tickersMap.values());
        },
      },
      mounted(){
          this.getExchangesList()
      },
      destroyed() {
        this.leaveRoom()
      },
    });
    </script>

    <style lang="sass" scoped>
    .transition-color-red-ticker
      animation-name: blinkingTextTickerRed
      animation-duration: 0.7s
      animation-direction: alternate

    .transition-color-green-ticker
      animation-name: blinkingTextTickerGreen
      animation-duration: 0.7s
      animation-direction: alternate

    @keyframes blinkingTextTickerRed
      50%	
        @apply text-red-500
    @keyframes blinkingTextTickerGreen
      50%	
        @apply text-green-500
    </style>```

When sharing code, please don’t use screenshots.

The people wanting to help you can’t copy code from screenshots and therefore can’t edit it.

Instead, share the code as text and make sure to use proper Syntax Highlighting

1 Like

On quick review of your code I don’t see anywhere that the blink animation class gets removed from the element. If you don’t remove the class then no animation will occur when you apply it to the same element again.

Thanks for your answer! I have tried two things to remove from the element

  1. this.mapOfColors.get (key) [getProp] = ‘text-current’
  2. this.mapOfColors.get (key) [getProp] = ‘’

Is there any other way to do it?

I didn’t notice it before, but your issue could be due to Vue 2’s change detection caveats.

I don’t believe Vue 2’s reactivity support Map and Set. Seems there’s a few discussions around the issue, including some possible workarounds: https://pretagteam.com/question/does-vue-support-reactivity-on-map-and-set-data-types