简体   繁体   English

如何从 JSON 获取数据?

[英]How can I get data from a JSON?

I m strugglin with a problem I cannot figure out. Im strugglin with a problem I cannot figure out. I m strugglin with a problem I cannot figure out. I m getting data from a JSON to write the DOM of my html (a store, I write the different items with that json). m strugglin with a problem I cannot figure out. I从 JSON 获取数据来编写我的 html 的 DOM(一个商店,我用那个 json 编写不同的项目)。 The problem starts when I try to get the json data out of the function, in order to push all the items into an array (the array will be the shopping cart).当我尝试从 function 中获取 json 数据以便将所有项目推入数组(该数组将是购物车)时,问题就开始了。 I`ve tried every thing I know and the only thing I get is undefined.我已经尝试了所有我知道的东西,但我得到的唯一东西是未定义的。 I need help!我需要帮助!

this is the code这是代码

//this is the JSON file

[{
    "id" : "cnj01",
    "form_id" : "cnj_form",
    "title" : "Conejita dormilona",
    "name" : "conejitadormilona",
    "description" : "Conejita tejida con hilo fino rosa, sin accesorios.",
    "description_mid" : "Conejita tejida al crochet con hilo mediano color rosa. Se pueden incluir accesorios como chaleco o bufanda.",
    "description_long" : "Conejita tejida al crochet con hilo mediano color rosa. Rellenada con vellón siliconado. La altura es de 22 cm. El accesorio incluído es una vincha tejida con el mismo tipo y color de hilo. También se pueden incluir accesorios como chaleco o bufanda con colores a elección.",
    "price" : 850,
    "cant" : 1,
    "image" : "images/products/conejita.jpg",
    "altimg" : "conejita dormilona - mununuras.ar - juguetes de apego",
    "stock" : 4
},
{
    "id" : "zrt01",
    "form_id" : "zrt_form",
    "title" : "Zorrito cariñoso",
    "name" : "zorritocarinoso",
    "description" : "Zorrito tejido en hilo fino con ojos de seguridad.",
    "description_mid" : "Este simpático zorrito viene con un ocico plástico y ojitos de seguridad para los mas chiquitos.",
    "description_long" : "Este simpático zorrito viene con un ocico plástico y ojitos de seguridad para los mas chiquitos. Rellenada con vellón siliconado. La altura es de 14 cm. Tejido en hilo mediano de color negro, blanco y marron anaranjado.",
    "price" : 950,
    "cant" : 1,
    "image" : "images/products/zorrito.jpg",
    "altimg" : "zorrito cariñoso - mununuras.ar - juguetes de apego",
    "stock" : 3
},
{
    "id" : "mds01",
    "form_id" : "mds_form",
    "title" : "Llavero medusa",
    "name" : "llaveromedusa",
    "description" : "Llavero medusa, con anilla metálica pequeña.",
    "description_mid" : "Medusa tejida al crochet con hilo fino. Posee anilla de metal cosida. Viene en tres tamaños.",
    "description_long" : "Medusa tejida al crochet con hilo fino. Posee anilla de metal cosida. Viene en tres tamaños grande (7cm), mediano (5cm) y chico (3cm). Rellena con vellón siliconado. Ideal para regalar!",
    "price" : 550,
    "cant" : 1,
    "image" : "images/products/medusa.jpg",
    "altimg" : "Llavero medusa - mununuras.ar - juguetes de apego",
    "stock" : 10
},
{
    "id": "plt01",
    "form_id" : "plt_form",
    "title" : "Colgante de pollitos",
    "name" : "colgantepollito",
    "description" : "Colgante de tres pollitos con anillo transparente.",
    "description_mid" : "Cogante de tres pollitos con anillo transparente. Ideal para adornar tus cortinas.",
    "description_long" : "Colgante de tres pollitos tejidos al crochet, ideal para adornar tus cortinas. Viene en un único tamaño (45cm). Los pollitos están rellenos con vellón siliconado.",
    "price" : 750,
    "cant" : 1,
    "image" : "images/products/pollito.jpg",
    "altimg" : "Colgante de tres pollitos - mununuras.ar - juguetes de apego",
    "stock" : 5
}
]


// product constructor
class Product {
    constructor (id, form_id, title, name, description, description_mid, description_long, price, cant, image, altimg, stock) {
        this.id = id;
        this.form_id = form_id;
        this.title = title;
        this.name = name;
        this.description = description;
        this.description_mid = description_mid;
        this.description_long = description_long;
        this.price = parseFloat(price);
        this.cant = parseInt(cant);
        this.image = image;
        this.altimg = altimg;
        this.stock = parseInt(stock);
        this.subtotal = this.price * this.cant;
    }
}

// this is where I want to push every item of the JSON//
let shoppingCart = new Array;


const req = new XMLHttpRequest();
req.open('GET', 'scripts/products.json', true);
req.send();
req.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {
        let data = JSON.parse(this.responseText);

        // this IS NOT WORKING
        data.forEach( (element) => {
            // this shows the correct data
            console.log(element);
            let product =  new Product (`${element.id}`, `${element.form_id}`, `${element.title}`, `${element.name}`, `${element.description}`, `${element.description_mid}`, `${element.description_long}`, `${element.price}`, `${element.cant}`, `${element.image}`, `${element.altimg}`, `${element.stock}`);
            shoppingCart.push(product);
//   these logs show me the correct data but when I do a console.log(shoppingCart) 
// out of this function, The only thig I get is "undefined".
            console.log(product);
            }
        )
        console.log(data);
        //the "for" below is writing my html without any problem.
        //That means the problem starts when I try to take the "data" content out of req.onreadystatechange = function ()
        // in order to push every item into shoppingCart
        for (item of data) {
            $("#show_products").append(`
            <article class="products__item">
            <div>
                <img src="${item.image}" alt="${item.altimg}">
            </div>
            <div class="products__item--description">
                <h3 tabindex=0>${item.title}</h3>
                <p tabindex=0>${item.description_mid}</p>
                <div class="products__item--description--buttons">
                    <a tabindex=0 href="#${item.id}_popup" class="know">know more</a>
                    <a tabindex=0 class="add" id="${item.form_id}">add to shopping cart</a>
                </div>
            </div>
        </article>
            <div id="${item.id}_popup" class="window__popup">
                <div class="container__popup">
                    <div class="popup"><a tabindex=0 href="" class="close__popoup">X</a>
                        <div><img src="${item.image}" alt="${item.altimg}"></div>
                            <div class="popup--description">
                                <div tabindex=0 class="title">${item.title}</div>
                                <p tabindex=0>${item.description_long}</p>
                            <div tabindex=0 class="price__popup">$950.-</div>
                            <a tabindex=0 class="add" id="zrt-btn2">add to shopping cart</a>
                        </div>
                    </div>
                </div>
            </div>
            `);
        }
    }
}
// here I can see al the items in the array
console.log(shoppingCart);

// but here, I get undefined
console.log(shoppingCart[0]);
console.log(shoppingCart[1]);
console.log(shoppingCart[2]);
// etc

I don´t know what I´m doing wrong.我不知道我做错了什么。

This is an issue involving async logic.这是一个涉及异步逻辑的问题。 Here's what's going on:这是发生了什么:

// #1
const shoppingCart = new Array
// ...
const req = new XMLHttpRequest();
// ...
req.onreadystatechange = function () {
  // ...
  // #3
}
// #2
console.log(shoppingCart)

The number signs in the above snippet denote the order of execution.上述代码段中的数字符号表示执行顺序。 First, you create this XMLHttpRequest() and attach an event listener to it.首先,您创建这个 XMLHttpRequest() 并将一个事件侦听器附加到它。 Then you attempt to log out the value of shoppingCart (which should be an empty list - Are you sure you read your output correctly and didn't get mixed up with your other console.logs?).然后您尝试注销 shoppingCart 的值(这应该是一个空列表 - 您确定您正确阅读了 output 并且没有与其他 console.logs 混淆吗?)。 At some point in the future, your request finishes and the callback is executed with your JSON data, which you then put into the array.在将来的某个时间点,您的请求完成并使用您的 JSON 数据执行回调,然后您将其放入数组中。

See the issue?看到问题了吗?

Any code that depends on this JSON data must be placed inside the XMLHttpRequest callback.任何依赖此 JSON 数据的代码都必须放在 XMLHttpRequest 回调中。 That is, move your console.log() stuff into that callback like so:也就是说,将您的 console.log() 内容移动到该回调中,如下所示:

const req = new XMLHttpRequest();
// ...
req.onreadystatechange = function () {
  // ...
  console.log(yourData)
}

If the callback starts getting really big, then split it up into multiple smaller functions.如果回调开始变得非常大,则将其拆分为多个较小的函数。

(As a side note - XMLHttpRequest is a pretty old and difficult-to-use API. In the future, I would recommend using the fetch API instead) (附带说明 - XMLHttpRequest 是一个非常古老且难以使用的 API。将来,我建议使用fetch API 代替)

Well, finally I made it work.好吧,最后我让它工作了。 Thanx scott for your help: This is what I came up with:感谢斯科特的帮助:这就是我想出的:

fetch('scripts/products.json')
    .then(response => response.json())
    .then(data => { let fetchedData = [];
                    data.forEach( (item) => {fetchedData.push(item);});
                    sessionStorage.setItem('storeItems', JSON.stringify(fetchedData));
    });

fetch is easier to use as scott said, and then I used a forEach to push the different items of the store into the array (fetchedData) and then put that array on sessionStorage.正如scott所说,fetch更容易使用,然后我使用forEach将商店的不同项目推送到数组(fetchedData)中,然后将该数组放在sessionStorage上。

Then I load that on the shoppingCart array and I can rearrange it as I want.然后我将它加载到 shoppingCart 数组中,我可以根据需要重新排列它。

It worked like a charm.它就像一个魅力。 I don´t know if this is the best way to do this but it works and hope this can help.我不知道这是否是最好的方法,但它有效,希望这能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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