简体   繁体   中英

Array in POST request body not iterable

I am building a private API for my website, and am attempting to ingest data passed to the program through an API endpoint. I am attempting to iterate over all items in an array stored at a key. The body of the POST request made to API endpoint is shaped like:

{
    "tracked": [
        {
            "categoryId": 100,
            "categoryName": "Cars",
            "items": [
                {
                    "item": "Red Car",
                    "itemId": "",
                    "limit": 1
                },
                {
                    "item": "Blue Car",
                    "itemId": "",
                    "limit": 1
                },
            ]
        },
        {
            "categoryId": 200,
            "categoryName": "Trucks",
            "items": [
                {
                    "item": "Red Truck",
                    "itemId": "",
                    "limit": 1
                },
                {
                    "item": "Blue Truck",
                    "itemId": "",
                    "limit": 1
                },
            ]
        }
    ]
}

My issue is: when attempting to iterate over the array at the key "tracked" my application throws an exception " TypeError: tracked.tracked is not iterable . Why is this, and how would I solve this issue? The value at tracked.tracked is clearly an array. Below is the code which is not functioning.

import * as functions from "firebase-functions";
import * as express from 'express'

// init express app
const app = express()

// my routings
const apiRoute = require("./api")

// enable json parsing
app.use(express.json())

// add routes to the express app.
app.use("/api", apiRoute)

exports.api = functions.https.onRequest(app)
router.route('/data/tracked').post( async (req, res) => {
    
    const tracked = req.body.tracked as Tracked
    const response = postTracked(tracked)
    res.status(200).send(response)

})
/**
 * Ingests a json of tracked items and categorys formatted as type Tracked
 * @param tracked json of categorys and their respective items being tracked
 * @returns response with indicated success.
 */

export const postTracked = async (tracked: Tracked) => {

    // set item id's in ingested json.
    const newTracked: Tracked = {
        tracked: [],
    }
    for (const cat of tracked.tracked) {
        const category: Category = {
            categoryId: cat.categoryId,
            categoryName: cat.categoryName,
            items: []
        }
        for (const itm of cat.items) {
            const itemId = `${cat.categoryId}-${generateRandomString(5)}`
            category.items.push({
                item: itm.item,
                itemId: itemId,
                limit: itm.limit,  
            } as Item)
        }
        newTracked.tracked.push(category);
        
    }

    // update the tracked list.
    await db.collection('trackers').doc('eBay').set(tracked, {merge: true})

    return responseBuilder(true, (await db.collection('trackers').doc('eBay').get()).data())
}

This function previously worked when I was not using express, and just firebase.functions.onCall as shown below.

const ingestTrackedJSON = functions.https.onCall(async (data, context) => {

    // set item id's in ingested json.
    const tracked: TrackedItems = {
        tracked: [],
    }
    for (const cat of ingest.tracked) {
        const category: Category = {
            categoryId: cat.categoryId,
            categoryName: cat.categoryName,
            items: []
        }
        for (const itm of cat.items) {
            const itemId = `${cat.categoryId}-${generateRandomString(5)}`
            category.items.push({
                item: itm.item,
                itemId: itemId,
                limit: itm.limit,  
            } as Item)
        }
        tracked.tracked.push(category);
        
    }

    // update the tracked list.
    db.collection('trackers').doc('eBay').set(tracked, {merge: true})

    return true;

you are trying to access to the "wrong" tracked . Here is what I mean:

export const postTracked = async (tracked: Tracked) => {

    // set item id's in ingested json.
    const newTracked: Tracked = {
        tracked: [],
    }
    for (const cat of tracked.tracked) { // <--- Here you should just use tracked

since you are already passing the body object. The correct line of code should be

    for (const cat of tracked) {

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM