weinde
weinde

Reputation: 1146

Typescript function returning NaN

In my app (I'm using Angular 7) I am trying to sum up weight of all items the client has selected to purchase. I want the addition to happen every time the user click the item. I have made a function getTotalWeight but it's returning NaN. I am getting my data from a JSON with such a structure:

{
  "steps": [
    {
      "id": "0",
      "name": "Model",
      "subname": "Choose your desired model",
      "category_type": 2,
      "image": "image-url",
      "subcategory": [],
      "options": [
        {
          "id": "0",
          "name": "Model name 1",
          "subtext": "lorem ipsum...",
          "description": "lorem ipsum dolor sit...",
          "category": "vwQGajMb9oxKVEPme75GPpDW2Od6gZBzXn4r3RLl",
          "image": "image-url",
          "thumb": "",
          "weight": "740.00",
          "price": "40821.1800"
        },
        {
          "id": "1",
          "name": "Model name 2",
          "subtext": "lorem ipsum...",
          "description": "lorem ipsum dolor sit...",
          "category": "vwQGajMb9oxKVEPme75GPpDW2Od6gZBzXn4r3RLl",
          "image": "image-url",
          "thumb": "",
          "weight": "780.00",
          "price": "35677.0600"
        },
      ]
    },
    {
      "id": "1",
      "name": "Addons",
      "subname": null,
      "description": "<p>Various other additional equipment for your choosen product...<\/p>",
      "options_select": "or",
      "category_type": 1,
      "image": "",
      "subcategory": [
        {
          "id": "0",
          "name": "Addon category 1",
          "subname": null,
          "options_select": "or",
          "category_type": 1,
          "image": "",
          "options": [
            {
              "id": "0",
              "name": "Manual step",
              "subtext": "Standard equipment",
              "description": "<p>Manual step<\/p>",
              "category": "PQLBd3o0MRav4mylN9pEZ1kJe2bxjVZXD8z6GWnw",
              "image": "image-url",
              "thumb": "",
              "weight": "0.00",
              "price": "0.0000"
            },
            {
              "id": "1",
              "name": "Manual step LIGHT",
              "subtext": "Standard equipment",
              "description": "<p>Manual step LIGHT<\/p>",
              "category": "PQLBd3o0MRav4mylN9pEZ1kJe2bxjVZXD8z6GWnw",
              "image": "image-url",
              "thumb": "",
              "weight": "0.80",
              "price": "236.9800"
            }
          ]
        },
        {
          "id": "1",
          "name": "Addon category 2",
          "subname": null,
          "description": null,
          "options_select": "or",
          "category_type": 1,
          "image": "",
          "options": [
            {
              "id": "0",
              "name": "super extra addon",
              "subtext": null,
              "description": null,
              "category": "8ljVoExnraWe9BMwd61qe1JLQPR43yNDq2ZvXb0k",
              "image": "image-url",
              "thumb": "",
              "weight": "11.00",
              "price": "405.8600"
            }
          ]
        }
      ],
      "options": []
    }
  ]
}

My code for summing weight is this:

  export class ConfiguratorComponent implements OnInit {
            data: any = {};
            ident: any = {};
            description: any = {};
            image: any = {};
            weight: number;
            options: any = {
                ident: '',
                name: '',
                description: '',
                image: '',
                weight: '',
                price: '',
            };
            selected: any = [];
            prices: any = {
                skupaj: '',
            };
            
            ngOnInit() {
                this.getData();
                this.getTotalWeight();
            }
        
            getData() {        
                this.httpClient.get(`${environment.apiUrl}`).subscribe(
                    data => {
                        console.log(data);
                        this.data = data;
        
                        let i = 0;
        
                        for (const step of data.steps) {
                            if (step.subcategory.length === 0) {
                                this.selected[i] = {
                                    'ident': step.ident,
                                    'name': step.name,
                                    'optionIdent': step.options[0].ident,
                                    'optionName' : step.options[0].name,
                                    'optionPrice' : step.options[0].price,
                                    'optionWeight' : step.options[0].weight,
                                    'categoryType' : step.category_type
                                };
                            }
                            i++;
                        }
       
                    },
                    error => {
                        console.log('Error', error);
                    }
                );
            }
        
        findElement(item) {
            return Object.values(this.selected).filter(e => e.optionIdent === item.ident).length > 0;
        }
    
        setOptionSelected(item, step) {
    
            if (Object.values(this.selected).filter(e => e.ident === step.ident).length > 0) {
                // var selectedKey = Object.keys(this.selected).find(e => e.ident === step.ident);
    
                const selectedKey = Object.values(this.selected).findIndex(x => x.ident === step.ident);
                this.selected[selectedKey] = {'ident': step.ident, 'name': step.name, 'optionIdent': item.ident, 'optionName' : item.name, 'optionPrice' : item.price, 'optionWeight' : item.weight, 'categoryType' : step.category_type};
            } else {
    
                const totalLength = Object.keys(this.selected).length;
                this.selected[totalLength] = {'ident' : step.ident, 'name': step.name, 'optionIdent' : item.ident, 'optionName' : item.name, 'optionPrice' : item.price, 'optionWeight' : item.weight, 'categoryType' : step.category_type};
            }
        }
    
        setOptionSubCatSelected(item, step, subcategory) {
    
            if (step.category_type === 1 && (Object.values(this.selected).filter(e => e.ident === subcategory.ident && e.optionIdent === item.ident).length > 0 ) ) {
                // extras
                // var selectedKey = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident && x.optionIdent === item.ident);
                // delete this.selected[selectedKey];
                const index: number = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident && x.optionIdent === item.ident);
                if (index !== -1) {
                    this.selected.splice(index, 1);
                }
            } else {
    
                if (Object.values(this.selected).filter(e => e.ident === subcategory.ident).length > 0) {
    
                    const selectedKey = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident);
                    this.selected[selectedKey] = {
                        'ident': subcategory.ident,
                        'name': subcategory.name,
                        'optionIdent': item.ident,
                        'optionName' : item.name,
                        'optionPrice' : item.price,
                        'optionWeight' : item.weight,
                        'categoryType' : subcategory.category_type
                    };
                } else {
                    const totalLength = Object.values(this.selected).length;
                    this.selected[totalLength] = {
                        'ident' : subcategory.ident,
                        'name': subcategory.name,
                        'optionIdent' : item.ident,
                        'optionName' : item.name,
                        'optionPrice' : item.price,
                        'optionWeight' : item.weight,
                        'categoryType' : subcategory.category_type
                    };
                }
            }
        }
    
        setCheckSelected(item, step, subcategory) {
    
            if (step.category_type === 1 && (Object.values(this.selected).filter(e => e.ident === subcategory.ident && e.optionIdent === item.ident).length > 0 ) ) {
    
                const index: number = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident && x.optionIdent === item.ident);
                if (index !== -1) {
                    this.selected.splice(index, 1);
                }
    
            } else {
                const totalLength = Object.keys(this.selected).length;
                this.selected[totalLength] = {
                    'ident' : subcategory.ident,
                    'name': subcategory.name,
                    'optionIdent' : item.ident,
                    'optionName' : item.name,
                    'optionPrice' : item.price,
                    'optionWeight' : item.weight,
                    'categoryType' : subcategory.category_type
                };
            }
        }
        
        getTotalWeight() {
            let totalWeight = 0;
            console.log('Weight start:', totalWeight);
            totalWeight = totalWeight + Number(this.selected.optionWeight);
            console.log('Weight now:', totalWeight);
            // prištevek doplačil
            this.doplacila.forEach((item, index) => {
                if (item.selected.optionWeight != null) {
                    totalWeight = totalWeight + Number(item.selected.optionWeight);
                    console.log('Weight now:', totalWeight);
                }
            });
            console.log('Total weight:', totalWeight);
            return totalWeight;
        }
    }

Where is the problem in my code?

Have I even approached this correctly or should I do it in a whole different way?

Upvotes: 0

Views: 397

Answers (1)

Chris Hamilton
Chris Hamilton

Reputation: 10954

You're not waiting for your get request to complete before trying to calculate. Put your getTotalWeight() call into your subscription.

  ngOnInit() {
    this.getData();
  }

  getData() {
    this.httpClient.get(`${environment.apiUrl}`).subscribe(
      (data) => {
        console.log(data);
        this.data = data;

        let i = 0;

        for (const step of data.steps) {
          if (step.subcategory.length === 0) {
            this.selected[i] = {
              ident: step.ident,
              name: step.name,
              optionIdent: step.options[0].ident,
              optionName: step.options[0].name,
              optionPrice: step.options[0].price,
              optionWeight: step.options[0].weight,
              categoryType: step.category_type,
            };
          }
          i++;
        }
        this.getTotalWeight()
      },
      (error) => {
        console.log('Error', error);
      }
    );
  }

Alernatively, to make your code more readable:

  ngOnInit() {
    this.httpClient.get(`${environment.apiUrl}`).subscribe(
      (data) => {
        this.parseData(data);
        this.getTotalWeight();
      },
      (error) => {
        console.log('Error', error);
      }
    );
  }

  parseData(data: any) {
    console.log(data);
    this.data = data;

    let i = 0;

    for (const step of data.steps) {
      if (step.subcategory.length === 0) {
        this.selected[i] = {
          ident: step.ident,
          name: step.name,
          optionIdent: step.options[0].ident,
          optionName: step.options[0].name,
          optionPrice: step.options[0].price,
          optionWeight: step.options[0].weight,
          categoryType: step.category_type,
        };
      }
      i++;
    }
  }

I have no idea what doplacila is referring to, but I imagine this is the totalWeight function you were attempting:

  getTotalWeight() {
    let totalWeight = 0;
    console.log('Weight start:', totalWeight);
    for (const item of this.selected) {
      if (item.optionWeight) {
        totalWeight += Number(item.optionWeight);
        console.log('Weight now:', totalWeight);
      }
    }
    console.log('Total weight:', totalWeight);
    return totalWeight;
  }

You've also written ident in your code, I believe you meant id.

    for (const step of data.steps) {
      if (step.subcategory.length === 0) {
        this.selected[i] = {
          ident: step.id,
          name: step.name,
          optionIdent: step.options[0].id,
          optionName: step.options[0].name,
          optionPrice: step.options[0].price,
          optionWeight: step.options[0].weight,
          categoryType: step.category_type,
        };
      }
      i++;
    }

Upvotes: 1

Related Questions