Issue
I am trying to fill up a component with leads coming from an API. I have a LeadService file as well as my vue template file. The issue I'm having, is I'm using an async call on my template file which works, but when I go to compute the values it throws a property does not exist on type
error. It actually works you can see the correct components behind the error message. I can't figure out how to make the error go away.
Here's the service class LeadService.ts
import ApiService from "@/core/services/ApiService";
interface Lead {
id: string;
first_name: string;
last_name: string;
lead_form_name: string;
email: string;
campaign: string;
timestamp: number;
mobile_number: string;
message: string;
medium: string;
city: string;
state: string;
leadType: string;
quality: string;
source: string;
call_link: string;
company: string;
country: string;
}
export default class LeadService {
getLeads() {
const accountInfo = JSON.parse(localStorage.getItem('accountInfo') || '{}');
ApiService.setHeader();
return ApiService.query("/leads", {params: {client_id : accountInfo.client_id}})
.then(({ data }) => {
let leadData: Lead[] = data['Items'];
return leadData;
})
.catch(({ response }) => {
return response;
});
}
}
Here is my vue template Leads.vue
<template>
<!--begin::Leads-->
<div class="row gy-5 g-xl-8 mb-8">
<div class="col-xxl-12">
<LeadTracker
:lead-data="leadData"
:updateQuality="updateQuality"
:key="componentKey"
/>
</div>
</div>
<div class="row gy-5 gx-xl-8 mb-8">
<div class="col-xxl-8">
<LeadMethods
chart-height="500"
:method-data="getLeadMethods"
></LeadMethods>
</div>
</div>
<!--end::Leads-->
</template>
<script lang="ts">
import { defineComponent, onMounted } from "vue";
import { setCurrentPageTitle } from "@/core/helpers/breadcrumb";
import LeadMethods from "@/components/leads/methods/LeadMethods.vue";
import LeadTracker from "@/components/leads/tracker/LeadTracker.vue";
import LeadService from "@/core/services/LeadService";
import ApiService from "@/core/services/ApiService";
export default defineComponent({
name: "leads",
components: {
LeadMethods,
LeadTracker,
},
data() {
return {
leadData: {},
}
},
beforeMount: async function() {
this.leadData = await new LeadService().getLeads()
},
setup() {
onMounted(() => {
setCurrentPageTitle("Lead Activity");
});
const sourceThreshold = 5;
return {
sourceThreshold,
componentKey: 0
};
},
computed: {
getLeadMethods(): object {
const leadMethods: Array<object> = [];
const totalLeads = this.leadData.length;
console.log('called getLeadMethods check this.leadData', this.leadData);
// Get the total number of Paid Media leads
const totalPaid = this.leadData.filter(
lead => lead.medium == "paid_media"
).length;
// Get the total number of Calls
const totalCall = this.leadData.filter(lead => lead.leadType == "call")
.length;
// Separate form leads from the rest
const formData = this.leadData.filter(lead => lead.leadType == "form");
// Make array for form names
const formTypes: Array<string> = [];
this.leadData.filter(lead => {
if (!formTypes.includes(lead.lead_form_name))
formTypes.push(lead.lead_form_name);
});
// Create objects for each form by name, push to leadMethods
formTypes.filter(type => {
let totalFormLeads = 1;
formData.filter(form => {
if (form.lead_form_name == type) totalFormLeads++;
});
const formMethod = {
name: type,
description: "Lorem ipsum dolor sit amet, consectetur.",
total: totalFormLeads,
percent: Math.round((totalFormLeads / totalLeads) * 100)
};
leadMethods.push(formMethod);
});
const callTracking = {
name: "Location Based Call-Tracking",
description: "Lorem ipsum dolor sit amet, consectetur.",
total: totalCall,
percent: Math.round((totalCall / totalLeads) * 100)
};
const paidSearch = {
name: "Paid Search",
description: "Lorem ipsum dolor sit amet, consectetur.",
total: totalPaid,
percent: Math.round((totalPaid / totalLeads) * 100)
};
leadMethods.push(callTracking, paidSearch);
return leadMethods;
}
}
});
</script>
The problem begins in my computed functions, where I start filtering this.LeadData
Essentially every filter throws a Property does not exist on type
error, but they do exist.
It's important to note, that when this.leadData
gets set, it is a Proxy.
Any help would be appreciated, I was wondering if I could just suppress the error although I don't like that solution.
For instance, in my first filter in the computed methods
// Get the total number of Paid Media leads
const totalPaid = this.leadData.filter(
lead => lead.medium == "paid_media"
).length;
medium
is a property of leadData
and I can actually console log it and it works just fine, but it still always throws the property does not exist on type
.
Solution
The type of leadData
is inferred from its declaration in data()
. It's initialized to {}
, which means its type is an immutable empty object (and no properties can be attached to it). However, leadData
is eventually assigned the return of LeadService().getLeads()
, so its type should actually be an array of Lead
objects.
To properly type leadData
, initialize it to an empty array with a type assertion of Lead[]
:
export default defineComponent({
data() {
return {
//leadData: {}, ❌
leadData: [] as Lead[], ✅
}
}
})
Answered By - tony19
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.