Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   не могу понять где ошибка (https://javascript.ru/forum/node-js-io-js/81176-ne-mogu-ponyat-gde-oshibka.html)

riaron 13.10.2020 19:51

не могу понять где ошибка
 
подскажите где ошибка

app.get('/orders/:page', (req, res) => {
        var connection = getMySQLConnection();
    var smartphone=[];
    var allsmartphone={};
    var smartphoneList=[];
    var allprice=0;
    var a;
    var b;
    var length;
	var orderids
    var raddr=req.connection.remoteAddress;
var start;
var end;
var allprice;
start=(req.params.page-1)*10;
end=req.params.page*10;
allprice=0;
    connection.connect(function(err) {
        if (err) throw err;
		var sql3='SELECT `id` FROM `orders`';
		var sql2='SELECT `orderid` FROM `orders` GROUP BY  `orderid`';
        var valuesii = [raddr];
		 connection.query(sql3, [], function (err, resulta) {
            if (err){
                console.log(err);

			}else{
				length=resulta.length;
				if(start<0){start=0;}
                if(end>(length-req.params.page*10)%10){end=length;}
			}
		 });connection.query(sql2, [], function (err, result) {
            if (err){
                console.log(err);

			}else{
				orderids=result;
			}
		 });
        var sql ='SELECT `id`,`prod`,`name`,`photo`,`price`,`sale`,`remote_adr`,`quantity` FROM `orders` LIMIT ?,?';

        connection.query(sql, [start,end], function (err, results) {
            if (err){
                console.log(err);

            }else{

				for(var j=0;j<1;j++) {
                    allprice = 0;
                    for (var i = 0; i < 1; i++) {
                        // Create the object to save the data.
                        b = results[i].price - results[i].price * results[i].sale / 100;
                        a = b * results[i].quantity;
                        allprice += a;
                        var smart = {
                            'id': results[i].id,
                            'prod': results[i].prod,
                            'name': results[i].name,
                            'photo': results[i].photo,
                            'sale': results[i].sale,
                            'price': results[i].price,
                            'tsale': b,
                            'vsego': a,
                            'quantity': results[i].quantity,
                            'allprice': allprice,
                        };
                        smartphone.push(smart);

                    }
                    allsmartphone[orderids[j]['orderid']][j] = smartphone;
                }
					var smartphoneList={
						'len':length,
						'jlen':end,
						'ip':valuesii,
					}
					console.log(orderids[1]['orderid']+" :smart: "+allsmartphone[orderids[1]['orderid']][0]['id']);
					res.render('orders', {"smartphoneList": smartphoneList,"allsmartphone": allsmartphone,'orderids':orderids});
            }
			});
		
		

        });
});




<table>
        <%for (var j=0;j<orderids.length;j++){%>
             <%for(var i=0;i<smartphoneList['jlen'];i++){%>
                <tr></tr>
                <tr>

                    <td class="leftitem" style="padding:10px;border-left:1px solid silver;border-top:1px solid silver;border-bottom:1px solid silver;">
                        <img class="imgind" style="height:200px;width:200px" src="<%= allsmartphone[orderids[j]['orderid']][i]['photo'];%>" />
                        <p>
                            Производитель: <%= allsmartphone[orderids[j]['orderid']][i]['prod'];%><br>
                            Модель:  <%= allsmartphone[orderids[j]['orderid']][i]['name'];%><br>
                            Цена: <%= allsmartphone[orderids[j]['orderid']][i]['price'];%><br>
                            <%if(allsmartphone[orderids[j]['orderid']][i]['sale']){%>Цена со скидкой:<%=allsmartphone[orderids[j]['orderid']][i]['tsale'];%>  <br><%}%>
                        </p>
                    </td>
                    <td style="padding:10px;border-top:1px solid silver;border-bottom:1px solid silver;">
                        <input type="text" id="quan" onblur="quanaddbasket(this.value,{<%= allsmartphone[orderids[j]['orderid']][i]['id'];%>})" name="quan" value="<%=allsmartphone[orderids[j]['orderid']][i]['quantity'];%>" />
                    </td>
                    <td style="padding:10px;border-top:1px solid silver;border-bottom:1px solid silver;">Всего: <%= allsmartphone[orderids[j]['orderid']][i]['vsego'];%><td>

                    </td>
                    <td style="padding:10px;border-top:1px solid silver;border-right:1px solid silver;border-bottom:1px solid silver;"></td>
                <tr>
                <tr></tr>
             <%}%>

        <%}%>
    </table>

voraa 13.10.2020 22:00

А в чем она проявляется?

Я вижу одну проблему
Обработчик connection.query(sql3 - вычисляет length
Обработчик connection.query(sql2 - вычисляет orderids
Которые потом используются в обработчике connection.query(sql1
Но connection.query - асинхронные. И нет никакой гарантии, что запрос sql1 не завершится раньше, чем sql2. И orderids будет не определен к этому моменту

riaron 15.10.2020 07:29

Как это решить?

voraa 15.10.2020 09:11

Цитата:

Сообщение от riaron
Как это решить?

Использовать Promise.
Я не большой знаток node, но вроде есть библиотека, для работы с mysql основанная на promise.

Можно и с этой попытаться самому сделать через Promise.
Эти запросы можно изобразить как то так
function pquery (con, sql, par) {
	return new Promise ( (res, rej) => {
		con.query (sql, par,  (err, result) => {
				if (err) {
					rej (err);
				} else {
					res (result);
				}
			})
	})
}

var sql3='SELECT `id` FROM `orders`';
var sql2='SELECT `orderid` FROM `orders` GROUP BY  `orderid`';
var sql1 ='SELECT `id`,`prod`,`name`,`photo`,`price`,`sale`,`remote_adr`,`quantity` FROM `orders` LIMIT ?,?';

Promise.all([
	pquery (connection, sql3, []).then( resulta => {
		length=resulta.length;
		if(start<0){start=0;}
		if(end>(length-req.params.page*10)%10){end=length;}
	}), 
	pquery (connection, sql2, []).then( result => {
		orderids=result;
	})
]).then ( () => {
	return pquery (connection, sql1, [start,end]).then ( results => {
		for(var j=0;j<1;j++) {
			allprice = 0;
			for (var i = 0; i < 1; i++) {
				// Create the object to save the data.
				b = results[i].price - results[i].price * results[i].sale / 100;
				a = b * results[i].quantity;
				allprice += a;
				var smart = {
					'id': results[i].id,
					'prod': results[i].prod,
					'name': results[i].name,
					'photo': results[i].photo,
					'sale': results[i].sale,
					'price': results[i].price,
					'tsale': b,
					'vsego': a,
					'quantity': results[i].quantity,
					'allprice': allprice,
				};
				smartphone.push(smart);
		 
			}
			allsmartphone[orderids[j]['orderid']][j] = smartphone;
		}
		var smartphoneList={
			'len':length,
			'jlen':end,
			'ip':valuesii,
		}
		console.log(orderids[1]['orderid']+" :smart: "+allsmartphone[orderids[1]['orderid']][0]['id']);
		res.render('orders', {"smartphoneList": smartphoneList,"allsmartphone": allsmartphone,'orderids':orderids});
		}
	);
}).catch (err => {
	console.log(err);
})


Запросы sql2 и sql3 могут выполняться параллельно. А запрос sql1 гарантированно только после того, как sql2 и sql3 будут исполнены

Ну или делать вложенные обратные вызовы.
Сначала делать запрос sql3, в его обратном вызове делать запрос sql2, а в его обратном вызове - запрос sql1.

По мне, через Promise - проще и понятнее.

riaron 15.10.2020 11:35

отредактировал сделал так
]).then ( () => {
	for(var j=0;j<orderids.length;j++) {
		allprice = 0;
			var sql1 ='SELECT `id`,`prod`,`name`,`photo`,`price`,`sale`,`remote_adr`,`quantity` FROM `orders` where `orderid`=? LIMIT ?,?';
		return pquery (connection, sql1, [orderids[j],start,end]).then ( results => {
				for (var i = 0; i < end; i++) {
					// Create the object to save the data.
					b = results[i].price - results[i].price * results[i].sale / 100;//166 строка
					a = b * results[i].quantity;
					allprice += a;
					var smart = {
						'id': results[i].id,
						'prod': results[i].prod,
						'name': results[i].name,
						'photo': results[i].photo,
						'sale': results[i].sale,
						'price': results[i].price,
						'tsale': b,
						'vsego': a,
						'quantity': results[i].quantity,
						'allprice': allprice,
					};
					smartphone.push(smart);
				}
			}
		);
			var smartphoneList={
				'len':length,
				'jlen':end,
			}
		allsmartphone[j] = smartphone;
		console.log(orderids);
			res.render('orders', {"smartphoneList": smartphoneList,"allsmartphone": allsmartphone,'orderids':orderids});
		}
	}).catch (err => {

выдает ошибку
TypeError: Cannot read property 'price' of undefined
at C:\xampp\htdocs\mysite.local\app.js:166:21
at processTicksAndRejections (internal/process/task_queues.js:97:5)

надо ли с функцией ниже что то делать?
function getMySQLConnection() {
return mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
database : 'elektronika'
});
}

voraa 15.10.2020 12:22

У вас в SQL стоит LIMIT start, end
Но это не более end записей.
А цикл
for (let i = 0; i < end; i++) {

Вы уверены, что каждый раз будет end записей, не меньше?

res.render('orders', {"smartphoneList": smartphoneList,"allsmartphone": allsmartphone,'orderids':orderids});
находится внутри цикла по j. Так действительно должно быть?

Далее. Мы используем асинхронные операции.
Вот, например
allsmartphone[j] = smartphone;
А smartphone тут еще не посчитан. Он будет посчитан, только когда исполнится соответствующий запрос. Javascript не ждет. Он запустил запрос, сказал: когда Promise разрешится, выполни то, что указано в then
и пошел выполнять дальше. Выполнил allsmartphone[j] = smartphone; и пошел на следующую итерацию цикла.

SuperZen 15.10.2020 14:30

как orderid и limit связаны?
зачем их доставать ) в цикле когда можно написать orderid in (...)

в общем, предлагаю переписать app.get('/orders/:page', (req, res) =>

все эти подсчеты можно выбрать одним селектом )

riaron 16.10.2020 11:26

как передать переменную length и массив orderids в последний then

SuperZen 16.10.2020 11:41

Promise
  .resolve({ data: [1, 2, 3] })
  .then(data => {
    return data
  })
  .then(dataAgain => {
    return dataAgain
  }).then(dataAgainAgain => {
    return Promise
      .resolve(dataAgainAgain)
      .then(dataAgainAgainAgain => {
        dataAgainAgainAgain.data.push(4)
        return dataAgainAgainAgain
      })
  }).then(dataAgainAgainAgainWith4 => {
    console.log(dataAgainAgainAgainWith4) // [1,2,3,4]
  })

riaron 16.10.2020 12:37

Можете на примере показать?

SuperZen 16.10.2020 13:38

к сожалению, все что выложили, это мертвый код ), и смысла его подгонять "чтобы заработало" нет, лучше сформулируйте: есть табличка(и) такие-то в них лежит то-то, делаю запрос такой-то, и хочу получить то-то...

voraa 16.10.2020 16:43

Цитата:

Сообщение от riaron
как передать переменную length и массив orderids в последний then

В каком коде?
Сначала у вас был один код. Я показал, как выполнять его с Promise. 3 запроса. Третий (sql1) должен выполняться после первых двух. Ничего передавать не надо было. length (start и end) считались в первом, orderids во втором, и к третьему запросу все должно быть уже вычbсленно.
Потом вы переделали код. Уже цикл с запросами...
Я этот код не совсем понимаю.
Он в принципе неверен.

riaron 16.10.2020 16:44

Как сжелать чтобы sql запрос выполнялся в цикле?

voraa 16.10.2020 16:50

Цитата:

Сообщение от riaron
Как сжелать чтобы sql запрос выполнялся в цикле?

Это зависит от запросов и того, как обрабатывается результат.
Если запросы и их обработка полностью независимы друг от друга, то их можно выполнять параллельно, а потом просто ждать, когда они завершатся. (использовать Promise.all)
Если каждый следующий должен ждать завершения предыдущего, то надо делать цепочку обещаний и обработок.

riaron 16.10.2020 17:35

хочу чтобы
сначала var sql3='SELECT `id` FROM `orders`'; по промису
потом
var sql2='SELECT `orderid` FROM `orders` GROUP BY `orderid` limit start,end';
в третьем промисе уже бес последующих промисов
var sql1 ='SELECT `id`,`prod`,`name`,`photo`,`price`,`sale`,`remote_ adr`,`quantity` FROM `orders` where orderid=?'; в цикле
не могу сделать так чтобы length и orderids передались в последний then
app.get('/orders/:page', (req, res) => {
    var connection = getMySQLConnection();
    var smartphone=[];
    var allsmartphone={};
    var smartphoneList=[];
    var allprice=0;
    var a;
    var b;
    var length;
	var orderids;
	var start;
	var end;
	var allprice;
	start=(req.params.page-1)*10;
	end=req.params.page*10;
	var sql3='SELECT `id` FROM `orders`';
	var sql2='SELECT `orderid` FROM `orders` GROUP BY  `orderid`';
	var sql1 ='SELECT `id`,`prod`,`name`,`photo`,`price`,`sale`,`remote_adr`,`quantity` FROM `orders` WHERE orderid=?';
	function pquery (con, sql, par) {
		return new Promise ( (res, rej) => {
			con.query (sql, par,  (err, result) => {
					if (err) {
						rej (err);
					} else {
						res (result);
					}
	
			});
	
		});
	}

	Promise.all([
		pquery (connection, sql3, []).then( resulta => {
			length=resulta.length;
			if(start<0){start=0;}
			if(end>(length-req.params.page*10)%10){end=length;}
		}),
		pquery (connection, sql2, []).then( result => {
			orderids=result;
		})
	]).then ( () => {
			

	for(var j=0;j<orderids.length;j++) {
		connection.connect(function(err) {
			connection.query(sql, [orderids[j]], function (err, result) {
				for (var i = 0; i < results.length; i++) {
					// Create the object to save the data.
					b = results[i].price - results[i].price * results[i].sale / 100;
					a = b * results[i].quantity;
					allprice += a;
					var smart = {
						'id': results[i].id,
						'prod': results[i].prod,
						'name': results[i].name,
						'photo': results[i].photo,
						'sale': results[i].sale,
						'price': results[i].price,
						'tsale': b,
						'vsego': a,
						'quantity': results[i].quantity,
						'allprice': allprice,
					};
					smartphone.push(smart);
				}
			});
			allsmartphone.push= smartphone;
		});
	});
					console.log(orderids);

			res.render('orders', {"smartphoneList": smartphoneList,"allsmartphone": allsmartphone,'orderids':orderids});*/
		});
});

riaron 18.10.2020 21:23

\app.js:159
bb[1]=resulta;
^^

SyntaxError: Unexpected identifier
←[90m at wrapSafe (internal/modules/cjs/loader.js:1053:16)←[39m
←[90m at Module._compile (internal/modules/cjs/loader.js:1101:27)←[39m
←[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)←[39m
←[90m at Module.load (internal/modules/cjs/loader.js:985:32)←[39m
←[90m at Function.Module._load (internal/modules/cjs/loader.js:878:14)←[39m
←[90m at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)←[39m
←[90m at internal/main/run_main_module.js:17:47←[39m

C:\xampp\htdocs\mysite.local>node app
C:\xampp\htdocs\mysite.local\app.js:159
bb[1]=resulta;
^^

SyntaxError: Unexpected identifier
←[90m at wrapSafe (internal/modules/cjs/loader.js:1053:16)←[39m
←[90m at Module._compile (internal/modules/cjs/loader.js:1101:27)←[39m
←[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)←[39m
←[90m at Module.load (internal/modules/cjs/loader.js:985:32)←[39m
←[90m at Function.Module._load (internal/modules/cjs/loader.js:878:14)←[39m
←[90m at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)←[39m
←[90m at internal/main/run_main_module.js:17:47←[39m



app.get('/orders/:page', (req, res) => {
    var connection = getMySQLConnection();
    var smartphone=[];
    var allsmartphone={};
    var smartphoneList=[];
    var allprice=0;
    var a;
    var b;
    var length;
	var orderids;
	var start;
	var end;
	var allprice;
	var bb=[];
	start=(req.params.page-1)*10;
	end=req.params.page*10;
	var sql3='SELECT `id` FROM `orders`';
	var sql2='SELECT `orderid` FROM `orders` GROUP BY  `orderid`';
	var sql1 ='SELECT `id`,`prod`,`name`,`photo`,`price`,`sale`,`remote_adr`,`quantity` FROM `orders` WHERE orderid=?';
	function pquery (con, sql, par) {
		return new Promise ( (res, rej) => {
			con.query (sql, par,  (err, result) => {
					if (err) {
						rej (err);
					} else {
						res (result);
					}
	
			});
	
		});
	}

	Promise.all([
		pquery (connection, sql3, []).then( resulta => {
			length=resulta.length;
			if(start<0){start=0;}
			if(end>(length-req.params.page*10)%10){end=length;}
		}),
		pquery (connection, sql2, []).then( result => {
			orderids=result;
		})
		 bb[1]=resulta;
		 bb[2]=result;
	]).then ( (bb) => {
			

	/*for(var j=0;j<orderids.length;j++) {
		connection.connect(function(err) {
			connection.query(sql, [orderids[j]], function (err, result) {
				for (var i = 0; i < results.length; i++) {
					// Create the object to save the data.
					b = results[i].price - results[i].price * results[i].sale / 100;
					a = b * results[i].quantity;
					allprice += a;
					var smart = {
						'id': results[i].id,
						'prod': results[i].prod,
						'name': results[i].name,
						'photo': results[i].photo,
						'sale': results[i].sale,
						'price': results[i].price,
						'tsale': b,
						'vsego': a,
						'quantity': results[i].quantity,
						'allprice': allprice,
					};
					smartphone.push(smart);
				}
			});
			allsmartphone.push= smartphone;
		});
	});*/
					console.log("len: " + bb[1]+" orderids: "+bb[2]);

			//res.render('orders', {"smartphoneList": smartphoneList,"allsmartphone": allsmartphone,'orderids':orderids});*/
		});
});

не передается bb

voraa 18.10.2020 23:29

Promise.all([
        pquery (connection, sql3, []).then( resulta => {
            length=resulta.length;
            if(start<0){start=0;}
            if(end>(length-req.params.page*10)%10){end=length;}
        }),
        pquery (connection, sql2, []).then( result => {
            orderids=result;
        })
         bb[1]=resulta;
         bb[2]=result;
    ])

Ну что за ерунда.
Promise.all
https://developer.mozilla.org/ru/doc...ts/Promise/all

Параметром функции должен быть МАССИВ Promise.
А это что такое?
bb[1]=resulta;
bb[2]=result;


var bb=[];
.....

.then ( (bb) => {

Это совсем разные bb
Первая - просто переменная
Вторая - параметр функции в then

voraa 18.10.2020 23:36

Цитата:

Сообщение от riaron
не могу сделать так чтобы length и orderids передались в последний then

А их и не надо передавать в then.
Они глобальные (внешние) в then они и так доступны.
Главное, что бы были к этому времени посчитаны.

voraa 19.10.2020 09:25

Цитата:

Сообщение от riaron
хочу чтобы
сначала var sql3='SELECT `id` FROM `orders`'; по промису
потом
var sql2='SELECT `orderid` FROM `orders` GROUP BY `orderid` limit start,end';

Только что заметил, что вы изменили запросы, и теперь sql2 должен выполняться после sql3, т.к. использует start,end, которые вычисляются после sql3.
Ну тут же совсем другая логика. И Promise.all совсем не нужен.

var sql3='SELECT `id` FROM `orders`';
 
pquery (connection, sql3, []).then( resulta => {
     length=resulta.length;
     if(start<0){start=0;}
     if(end>(length-req.params.page*10)%10){end=length;}

     var sql2='SELECT `orderid` FROM `orders` GROUP BY  `orderid` limit '+ start +', '+ end';

      return  pquery (connection, sql2, []).then( result => {
            orderids=result;
     })
})

riaron 19.10.2020 20:16

так не работает
ничего не выдает т.е. не входи в цикл j
app.get('/orders/:page', (req, res) => {
    var connection = getMySQLConnection();
    var smartphone=[];
    var allsmartphone=[];
    var smartphoneList=[];
    var allprice=0;
    var a;
    var b;
    var length;
	var orderids;
	var start;
	var end;
	var allprice;
	start=(req.params.page-1)*10;
	end=req.params.page*10;
	var sql2='SELECT `orderid` FROM `orders` GROUP BY  `orderid`';
	var sql1 ='SELECT `id`,`prod`,`name`,`photo`,`price`,`sale`,`remote_adr`,`quantity` FROM `orders` WHERE orderid=?';
	connection.connect(function(err) {
		if(err){
			console.log(err);
		}else{
				connection.query(sql2, [], function (err, resulta) {        
			length=resulta.length;
			if(start<0){start=0;}
			if(end>(length-req.params.page*10)%10){end=length;}
				orderids=resulta;
	
	for(var j=0;j<orderids.length;j++) {
	    smartphone=[];

			connection.query(sql1, [orderids[j]], function (err, results) {
				if(err){
					console.log(err);
				}else{
					for (var i = 0; i < results.length; i++) {
						// Create the object to save the data.
						b = results[i].price - results[i].price * results[i].sale / 100;
						a = b * results[i].quantity;
						allprice += a;
						var smart = {
							'id': results[i].id,
							'prod': results[i].prod,
							'name': results[i].name,
							'photo': results[i].photo,
							'sale': results[i].sale,
							'price': results[i].price,
							'tsale': b,
							'vsego': a,
							'quantity': results[i].quantity,
							'allprice': allprice,
						};
						smartphone.push(smart);
						console.log(smartphone);
										console.log(orderids);
	
					}
				}
			});
		
					//allsmartphone[orderids[j]].push(smartphone);
 
	};
					

			//res.render('orders', {"smartphoneList": smartphoneList,"allsmartphone": allsmartphone,'orderids':orderids});
		});		
};
});
});


Часовой пояс GMT +3, время: 00:02.