v2.5.2
Giriş yap

unexpected number hatası

arlihakan
29 defa görüntülendi

<script type="text/javascript">

document.querySelector('#add-item').addEventListener('click', function()
{
    document.querySelector('#orderTable tbody').innerHTML += `
        <tr>
            <td>
                <select asp-items="@Model.Products" asp-for="@Model.OrderDetail.ProductId" class="form-select">
                @{
                    if (Model.Products.Count > 0)
                    {
                        <option>Lütfen ürün seçiniz</option>
                        @foreach (var item in Model.Products)
                        {
                            <option value="@item.Value">@item.Text</option>
                        }
                    }
                    else
                    {
                        <option>Hiçbir ürün yok</option>
                    }
                }
                </select>
            </td>
            <td>
                <div class="m-0">
                    <input asp-for="@Model.OrderDetail.Quantity" class="form-control" value="" />
                </div>
            </td>
            <td>
                <button type="button" class="btn btn-outline-danger" id="btn_remove">
                    Öğeyi Sil
                </button>
            </td>
        </tr>
    `;
});

document.querySelector('#btn_remove').addEventListener('click', function(){
    var row = document.querySelector("#orderTable").rows.length - 1;
    document.querySelector('#orderTable tbody').removeChild();
});

</script>

Cevap yaz
Cevaplar (2)
ebykdrms
7 gün önce

Ben .NET kullanmadığım için atladığım bir husus var.
Razor, javascript içindeki string ifadede bulunan html formlarını işleyemez sanıyorum.

<script type="text/javascript">

    // select'e eklenecek option'ların string'ini oluşturuyorum.
    // Bu bir form işleme değil, sıradan bir foreach döngüsü. Razor bunu işleyecektir.
    var productOptions = `
        <option>Lütfen ürün seçiniz</option>
        @foreach (var item in Model.Products)
        {
            <option value="@item.Value">@item.Text</option>
        }
    `;

    // #add-item'e basıldığında tabloya satır eklenmesi
    // Burada select'i razor'un düzenlemesi için asp-* attribute'leri eklemiyorum.
    // Ayrıca silme butonunun da id ile değil class ile seçilebilmesi için btn-remove ifadesini class olarak yazıyorum.
    document.querySelector('#add-item').addEventListener('click', function () {
        document.querySelector('#orderTable tbody').innerHTML += `
            <tr>
                <td>
                    <select class="form-select">
                        ${productOptions}
                    </select>
                </td>
                <td>
                    <div class="m-0">
                        <input type="number" class="form-control" />
                    </div>
                </td>
                <td>
                    <button type="button" class="btn btn-outline-danger btn-remove">
                        Öğeyi Sil
                    </button>
                </td>
            </tr>
        `;
    });

    // Silme butonları da DOM'a dinamik olarak ekleneceği için olay dinleyicinin buna göre düzenlenmesi gerekir.
    // #orderTable > tbody daha önce DOM'da bulunuyorsa, click olay dinleyicisini buna verebiliriz.
    // tbody'nin herhangi bir yerine click edildiğinde bu click edilen yerin btn-remove class'ına sahip olup olmadığına bakarak işlem yaparız.
    // Yine karışmaması için, bu tıklanan butonun kapsayıcısı olan tr'nin silinmesi için e.target.closest('tr') ile satırı seçip .remove() ile sileriz.
    document.querySelector('#orderTable tbody').addEventListener('click', function (e) {
        if (e.target && e.target.classList.contains('btn-remove')) {
            e.target.closest('tr').remove();
        }
    });
</script>

Bu script'in çalışabileceği örnek bir html kodu:
Aşağıdaki kodu, yukarıda yazdıklarımı prompt ederek Chat GPT'ye oluşturttum:

<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sipariş Ekleme</title>
    <!-- Bootstrap için CSS -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <h2>Sipariş Ekleme</h2>
        
        <!-- Sipariş Ekle Butonu -->
        <button id="add-item" type="button" class="btn btn-primary mb-3">Yeni Sipariş Ekle</button>

        <!-- Sipariş Tablosu -->
        <table id="orderTable" class="table table-bordered">
            <thead>
                <tr>
                    <th>Ürün</th>
                    <th>Miktar</th>
                    <th>İşlem</th>
                </tr>
            </thead>
            <tbody>
                <!-- Başlangıçta tablo boş -->
            </tbody>
        </table>
    </div>

    <!-- Razor'dan gelecek JavaScript kodu -->
    <script type="text/javascript">

        // Ürün dropdown seçeneklerini Razor ile JS değişkenine aktar
        var productOptions = `
            <option>Lütfen ürün seçiniz</option>
            @foreach (var item in Model.Products)
            {
                <option value="@item.Value">@item.Text</option>
            }
        `;

        // Yeni öğe ekleme işlemi
        document.querySelector('#add-item').addEventListener('click', function () {
            document.querySelector('#orderTable tbody').innerHTML += `
                <tr>
                    <td>
                        <select class="form-select">
                            ${productOptions}
                        </select>
                    </td>
                    <td>
                        <div class="m-0">
                            <input type="number" class="form-control" />
                        </div>
                    </td>
                    <td>
                        <button type="button" class="btn btn-outline-danger btn-remove">
                            Öğeyi Sil
                        </button>
                    </td>
                </tr>
            `;
        });

        // Silme işlemi (Olay delegasyonu)
        document.querySelector('#orderTable tbody').addEventListener('click', function (e) {
            if (e.target && e.target.classList.contains('btn-remove')) {
                e.target.closest('tr').remove();
            }
        });
    </script>

    <!-- Bootstrap için JS -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
ebykdrms
8 gün önce

Öncelikle, lütfen soru hazırlarken biraz daha özenli olun.

Kısaca cevap: Hatanın alındığı satıra bakmak gerek.

Uzunca cevap:
Derlenmiş kod üzerinden yorum yapalım.

Model.Products.Count = 0 geldiğini varsayalım.

Bu durumda istemciye iletilen sayfa şu şekilde olur:

<script type="text/javascript">
    document.querySelector('#add-item').addEventListener('click', function() {
        document.querySelector('#orderTable tbody').innerHTML += `
            <tr>
                <td>
                    <select class="form-select" name="OrderDetail.ProductId">
                            <option>Hiçbir ürün yok</option>
                    </select>
                </td>
                <td>
                    <div class="m-0">
                        <input class="form-control" name="OrderDetail.Quantity" value="" />
                    </div>
                </td>
                <td>
                    <button type="button" class="btn btn-outline-danger" id="btn_remove">
                        Öğeyi Sil
                    </button>
                </td>
            </tr>
        `;
    });
    
    document.querySelector('#btn_remove').addEventListener('click', function() {
        var row = document.querySelector("#orderTable").rows.length - 1;
        document.querySelector('#orderTable tbody').removeChild();
    });
</script>

Burada unexpected number hatasını verebilecek, number'larla işi olan gördüğüm kadarıyla sadece şu kod var:

var row = document.querySelector("#orderTable").rows.length - 1;

O halde document.querySelector("#orderTable").rows.length kodu bir number dönmüyor demektir.
.length kodu array'ler için mutlaka bir sayı döner.
O halde document.querySelector("#orderTable").rows değeri bir array değil.
Normalde <table /> elementleri için .rows kodu mutlaka bir array döner. Eğer seçici (document.querySelector("#orderTable")), <table /> dışında bir element seçmiş olsaydı null dönerdi ve null.rows gibi bir komuta dönüşürdü. Bu da Uncaught TypeError: Cannot read properties of null (reading 'rows') gibi bir hata fırlatırdı.
O halde document.querySelector("#orderTable") kodu herhangi bir element dönmüyor. .querySelector() fonksiyonu seçicisi ile bir element bulamazsa null döner.
O halde unexpected number hatası doğrudan değil, dolaylı bir nedenle ortaya çıkıyor.
Yani hatanın alındığı satıra bakmak gerekir. Hata burada oluşmuyor gibi görünüyor.

Kurgusal olarak hatanın nerede olabileceğini düşününce aklıma şu geliyor:
#btn_remove id'li elemente click edildiğinde, DOM'da henüz bir #orderTable id'li element yoktur. Yani henüz DOM'a basılmamıştır.
Bu durumda row değişkeni NaN (Not a Number) değeri alır. Başka bir satırda row değeri ile bir işlem yapılmak istenirse, doğrudan değil ama dolaylı olarak bir hatalar silsilesi oluşup unexpected number hatasıyla karşılaşılabilir. Yani yine hatanın oluştuğu satıra, hatta varsa hatalar silsilesine bakmak gerek.

Bir diğer sorun da, #add-item elementine her basılışta #orderTable tbody elementi içine bir <tr /> elementi eklenmesiyle ilgili.
Çünkü eklenen her satırın içinde #btn_remove id'li bir buton da ekleniyor. Ama bir id değeri sayfa içinde sadece 1 tane olur. Burada, eklenen her satırın içinde aynı id'ye sahip birer buton oluşmuş oluyor.
document.querySelector('#btn_remove') ile seçim yapıldığında aslında her zaman ilk satırdaki buton seçilmiş oluyor.
Ama kodun paylaşılan kısmı için konuşursak, unexpected number hatası doğrudan bu nedenle oluşmuyordur. Ama buna bağlı dolaylı bir nedenle oluşuyor olabilr. Yani yine hatanın oluştuğu satıra bakmak gerek.

Bir diğer sorun da, document.querySelector('#btn_remove') seçicisi çalıştığı sırada henüz DOM'da #btn_remove id'li bir element olmaması.
Yani aslında bu komut çalıştığı sırada DOM'da hiç #btn_remove id'li element yoksa elementi seçmek mümkün değil. Böylece eklenen click olayı dinleyicisi de çalışmayacaktır. Hatta muhtemelen null.addEventListener(...) gibi bir yorumlama yapılacağı için yine bir TypeError alınıyordur. Ama tabi sayfada böyle bir element varsa o ayrı...
Tabi yine kodun paylaşılan kısmı için unexpected number hatası doğrudan bu nedenle oluşmuyordur.

SyntaxError: Unexpected number hatasıyla örneğin şöyle bir kodda karşılaşılır:

console.log(4 8 15 16 23 42);

Yani bu hata javascript'te syntax hatası varsa alınır. Yanlış bir operatör kullanımı veya number ve string arasına boşluk koymak gibi) olduğu durumlarda ortaya çıkar Kod yorumlanırken number beklenmeyen bir yerde number ile karşılaşılmasıyla bu hata fırlatılır.

Paylaştığın kodda syntax hatası oluşturacak bir yere rastlamadım. >>> Hatanın alındığı satıra bakmak gerek.