# Building a simple candlestick chart using Docker, FastAPI, and Vue 3 - Part 9

In the [last article](https://jeffpohlmeyer.com/candlestick-docker-fastapi-vue-part-8) we handled errors in the response from our FastAPI backend.
We also added in a bit of extra code to process the data, and the `postProcessData` method actually created `data` and `volData` elements, though we didn't do anything with it.
In this article we'll touch on emitting an event back to the parent component and passing data down to another component to use for charting purposes.

## Passing data to `App.vue`
### Finishing off processing data
We left off with `data` and `volData` elements defined in `Selections.vue`, and we need to somehow pass them up into `App.vue` and then down into another component that we'll create.
First, we need to actually return data from our `postProcessData` method.
We _could_ just emit the event directly from that method but it's better to keep each method focused on its own purpose.
Thus, the updated method will look like
```javascript
const postProcessData = (res) => {
  // Parse dates
  const formatDate = (d) => new Date(d).toISOString().substr(0, 10);
  const dates = res.map((e) => e.date).sort();
  state.startDate = formatDate(dates[0]);
  state.endDate = formatDate(dates[dates.length - 1]);

  // Format the data
  const data = res.map((e) => ({
    x: new Date(e.date),
    y: e.data,
  }));
  const volData = res.map((e) => ({
    x: new Date(e.date),
    y: e.volume ?? 0,
  }));

  return {
    series: [{data}],
    symbol: state.symbol,
    interval: state.interval,
    volume: [{name: 'volume', data: volData}]
  }
};
```
We are returning the data in this manner because we have already set four data elements in `App.vue`
```javascript
const series = ref([]);
const symbol = ref('');
const interval = ref('Daily');
const volume = ref([])
```
Thus we will want to set these values for use in the eventual chart component, so formatting the emitted data in this manner will make things easier in general.
The `series` and `volume` data are formatted the way they are because the charting platform we'll be using is ApexCharts and the data structure needs to be in the format set above.

Then we need to update `handleSubmit` to get this data and emit it to the `App.vue` component.
```javascript
const handleSubmit = async () => {
    v$.value.$validate();
    if (!v$.value.$invalid) {
        loading.value = true;
        try {
            const url = preProcessData();
            const res = await fetchData(url);
            const payload = postProcessData(res);

            emit('setData', payload);
        } catch (err) {
            console.log('err', err);
            dialog.value = true;
        }
        loading.value = false;
    }
};
```
### Emitting the event
In order to do this, we need to update our code in two other places.
First, we need to update the `setup` method in `Selections.vue` to include the `emit` handler
```javascript
export default defineComponent({
  components: { JVPDialog, JVPInput, JVPSelect },
  emits: ['setData'],
  setup(_, { emit }) {
```
The `_` in the `setup` method is because we're not actually using props anywhere in this component.
You can pass in the `props` argument but it won't do anything.

We then also need to listen for the event in `App.vue`.
This will involve adding the event listener onto the `Selections` element in the `template`, but also adding a method to handle this data in the `setup` function.
```vue
<template>
  <div class="h-screen bg-gray-200">
    <Selections class="px-4" @setData="setData" />
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue';
import Selections from './components/Selections.vue';

export default defineComponent({
  components: { Selections },
  setup() {
    const series = ref([]);
    const symbol = ref('');
    const interval = ref('Daily');
    const volume = ref([]);

    const setData = (payload) => {
      console.log('in setData');
      console.log(payload);
    };

    return { series, symbol, interval, volume, setData };
  },
});
</script>
```
Upon making these adjustments and submitting a request for data for $MSFT the resulting console looks like
![Screen Shot 2022-01-05 at 5.24.24 PM.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641423136896/pYzKMsC0e.png)
## Charting the data
### Organizing data in `App.vue`
Now that we have the data in `App.vue` we will need to store it instead of just logging it to the console.
This is fairly straightforward
```javascript
const setData = (payload) => {
  series.value = payload.series
  symbol.value = payload.symbol
  interval.value = payload.interval
  volume.value = payload.volume
}
```
This seems fairly verbose, though not debilitatingly so.
### Creating a Chart.vue component
We now need a component to hold this data and eventually render the chart.
```vue
<template>
  <div>
    <div>
      {{ symbol }}
    </div>
    <div>
      {{ interval }}
    </div>
    <div>
      {{ series }}
    </div>
    <div>
      {{ volume }}
    </div>
  </div>
</template>

<script>
import { defineComponent } from 'vue';
export default defineComponent({
  props: {
    symbol: {
      type: String,
      required: true,
    },
    interval: {
      type: String,
      required: true,
    },
    series: {
      type: Array,
      required: true,
    },
    volume: {
      type: Array,
      required: true,
    },
  },
  setup(props) {
    return {
      ...props,
    };
  },
});
</script>
```
We then update `App.vue` to include this component
```vue
<template>
  <div class="h-screen bg-gray-200">
    <Chart
      :series="series"
      :symbol="symbol"
      :interval="interval"
      :volume="volume"
    />
    <Selections class="px-4" @setData="setData" />
  </div>
</template>

<script>
import { defineComponent, ref, reactive } from 'vue';
import Selections from './components/Selections.vue';
import Chart from './components/Chart.vue';

export default defineComponent({
  components: { Selections, Chart },
  setup() {
    const series = ref([]);
    const symbol = ref('');
    const interval = ref('Daily');
    const volume = ref([]);

    const setData = (payload) => {
      series.value = payload.series
      symbol.value = payload.symbol
      interval.value = payload.interval
      volume.value = payload.volume
      console.log('data fetched and set')
    };

    return { series, symbol, interval, volume, setData };
  },
});
</script>
```
And we click the button to fetch the data and we get the following
![Screen Shot 2022-01-05 at 5.41.24 PM.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641423176395/pWaayCSC8.png)
which doesn't make any sense since the data has clearly been set in `App.vue`.
What's actually happening is
- The `Chart.vue` component is mounted with data that exists in `App.vue` at first
- Data is fetched from `Selections.vue` and passed up to `App.vue`
- Data is then passed down to `Chart.vue`
- __Nothing is telling `Chart.vue` to check to see if props changed to trigger a re-render!!!__

### Watching for data changes
There are a few ways that we can make sure that `Chart.vue` will watch the props and re-paint the DOM when data are updated.
The most straight-forward way is to make all four elements computed properties in `Chart.vue`.
We will need to import `computed` at the top of the `script` tag, and then do the following
```javascript
setup(props) {
  const symbol = computed(() => props.symbol.toUpperCase());
  const interval = computed(() => props.interval);
  const series = computed(() => props.series);
  const volume = computed(() => props.volume);
  return {
    symbol,
    interval,
    series,
    volume,
  };
},
```
[Computed properties](https://v3.vuejs.org/guide/computed.html) are like reactive elements in a Vue component.
Any time the data inside the anonymous function for the computed property is updated then the resulting element will also update.
We could utilize [watchers](https://v3.vuejs.org/guide/computed.html#watchers) but again, this is a fairly straightforward solution for what we need.
Upon doing this and fetching the data again we see
![Screen Shot 2022-01-05 at 5.49.02 PM.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641423199873/MXRF6ds7m.png)

and we have the updated data as anticipated.

In the [next article](https://jeffpohlmeyer.com/candlestick-docker-fastapi-vue-part-10) we'll install and include [Vue3 ApexCharts](https://www.npmjs.com/package/vue3-apexcharts) to render out the stock chart as well as the volume chart.
