0

I am trying to toggle a class based on isNight's truth value:

<div :class="['app-bg', { nightBg: isNight }]"></div>

I have the isNight prop set to false as shown:

export default {
  name: 'Result',
  data(){
    return {
      error: null,
      weather: null,
      weatherIcon: null,
      isNight: false
    }
  },
  . . .

I have a function in computed that returns a true or false based on some data:

  computed: {
    nightChecker() {
      return this.weatherIcon.slice(2) == 'n' ? true : false
    }
  },

How do I update the isNight prop to reflect the return value of nightChecker()? I tried isNight: nightChecker, but that throws an error.

EDIT: Thank you to everyone who helped me understand this more. As you may can tell, I am new to Vue and am still wrapping my head around it.

supernova
  • 127
  • 1
  • 1
  • 12
  • FYI, the `? true : false` is completely redundant – Phil Mar 01 '21 at 23:39
  • 1
    I don't think you are supposed to change your props from within the component (props are meant to be changed by the parent component). You probably want another computed method that uses the prop and the `nightChecker` method and use it to toggle the class. – arieljuod Mar 01 '21 at 23:39
  • sorry I was confused because the OP said `prop` but it's actually the `data` which is actually internal for the component – arieljuod Mar 01 '21 at 23:44

2 Answers2

2

Assuming the error is from weatherIcon starting null, it's because null doesn't have a slice method. You don't need slice anyway.

  • slice returns a range, but since you're only testing against 1 character, it makes more sense to evaluate the index
  • By not using slice, there is no error even when weatherIcon is null
  • As mentioned in comments, the ternary is unnecessary, you can return the value of the equality check
computed: {
  nightChecker() {
    return !!this.weatherIcon && this.weatherIcon[2] === 'n';
  }
}

The double not is necessary because null && false is null, not false

Here's a demo if this is still unclear:

new Vue({
  el: "#app",
  data() {
    return {
      weatherIcon: null
    }
  },
  computed: {
    nightChecker() {
      return !!this.weatherIcon && this.weatherIcon[2] === 'n';
    }
  },
  methods: {
    toggle() {
      this.weatherIcon = this.weatherIcon === 'tonight' ? 'today' : 'tonight'
    }
  },
});
<div id="app">
  Is it night? {{ nightChecker }} <br>
  <button @click="toggle">Toggle day/night</button>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
Dan
  • 59,490
  • 13
  • 101
  • 110
  • The `nightChecker()` method still doesn't do anything to the `isNight` prop that I am trying to change. – supernova Mar 02 '21 at 00:52
  • It's not a method, it's a computed. A computed should never change a data property, it just computes something new. There is no need for both, you use it instead of `isNight`, which you can eliminate. – Dan Mar 02 '21 at 01:12
  • Think of a computed as a data property that changes itself. It would be pointless to set the value to `isNight`. – Dan Mar 02 '21 at 01:24
0

idk if i got the question right, but

data(){
  return {
    error: null,
    weather: null,
    weatherIcon: null,
    isNight: this.nightChecker()
  }
},
computed(){
  nightChecker(){
    return this.weatherIcon && this.weatherIcon.slice(2) === 'n';
  }
}
Maxi
  • 31
  • 1
  • 8