totaljs / framework4

Total.js framework v4
https://www.totaljs.com
Other
97 stars 36 forks source link

controller.status is undefined ? #9

Closed aalfiann closed 3 years ago

aalfiann commented 3 years ago

How to set custom statusCode from controller?

I've tried like this at controller default.js

exports.install = function() {
    ROUTE('GET /', test);
};

function test() {
    var self = this;
    console.log(self.controller);
    self.controller.status = 201;
    self.plain('REST Service {0}\nVersion: {1}'.format(CONF.name, CONF.version));
}

the output is

undefined
======= 2021-02-04 12:17:27: default ---> TypeError: Cannot set property 'status' of undefined (http://localhost:8000/) TypeError: Cannot set property 'status' of undefined
    at Controller.test (/home/aziz/Work/nodejs/totaljsv4/controllers/default.js:8:28)
    at IncomingMessage.PROTO.$total_execute2 (/home/aziz/Work/nodejs/totaljsv4/node_modules/total4/index.js:14937:31)
    at IncomingMessage.PROTO.$total_execute (/home/aziz/Work/nodejs/totaljsv4/node_modules/total4/index.js:14903:9)
    at IncomingMessage.PROTO.$total_prepare (/home/aziz/Work/nodejs/totaljsv4/node_modules/total4/index.js:15224:9)
    at IncomingMessage.PROTO.$total_end (/home/aziz/Work/nodejs/totaljsv4/node_modules/total4/index.js:14834:9)
    at Framework.F.$requestcontinue (/home/aziz/Work/nodejs/totaljsv4/node_modules/total4/index.js:7503:9)
    at Server.F.listener (/home/aziz/Work/nodejs/totaljsv4/node_modules/total4/index.js:7250:5)
    at Server.emit (events.js:198:13)
    at parserOnIncoming (_http_server.js:695:12)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:111:17)

And is it posible to convert default 404, 408, 500 html page into json? how?

petersirka commented 3 years ago

self === Controller, so update your code to:

self.status = 201;
aalfiann commented 3 years ago

thank you it's work but how to get $ in controller ?

petersirka commented 3 years ago
function test() {
    // this === controller
    var $ = this;
    var self = this;

    $.success();
}
petersirka commented 3 years ago

Sorry I forgot to answer:

And is it posible to convert default 404, 408, 500 html page into json? how?

Yes. Please update Total.js 4 framework from NPM $ npm update total4. I have added auto-serialization errors via ErrorBuilder when the request contains XHR header.

But if your requests don't contain XHR header, then you need to register system routes:

Example:

ROUTE('#400', function() {
    this.status = 400;
    this.json({ error: 'Bad requests' });
});

ROUTE('#401', function() {
    this.status = 401;
    this.json({ error: 'Unauthorized' });
});
aalfiann commented 3 years ago

I have a plan to create a global function which is use $, so it can be used at middleware also at controller.

for example

function successResponse($, message) {
  $.controller.status = 200;
  $.callback();
}

that function is work fine in middleware but fail when use at controller. have any solution?

petersirka commented 3 years ago

Describe me your case, perhaps we will have a better solution.

aalfiann commented 3 years ago

Sorry for long reply because I have to create a reduced test case to make this simpler.

definitions/handler.js This handler class is working fine when I used at MIDDLEWARE also when used in SCHEMA

'use strict';

function success ($, message, response = {}) {
    $.controller.status = 200
    const newdata = {
        status: 'success'
    }
    Object.assign(newdata, response);
    return $.controller.json(_defaultMsg(message, 200, newdata));
}

function error ($, error, message = 'Bad Request', response = {}) {
    $.controller.status = 400
    const newdata = {
        status: 'error',
        error: error
    }
    Object.assign(newdata, response);
    return $.controller.json(_defaultMsg(message, 400, newdata));
}

function _defaultMsg (message, code, obj) {
    const data = {
      code: code,
      message: message
    }
    Object.assign(data, obj);
    return data;
}

module.exports = { success, error }

controller/default.js But I can't use my handler.js class in controller. example test route

exports.install = function() {
    ROUTE('GET /middleware', ['#authorize']); // This work (this should be always error because no x-token header in GET request)
    ROUTE('GET /', test);
};

// BELOW HERE NOT WORK
var handler = require(F.path.definitions('handler'));

function test() {
    var self = this;
    handler.success(self, 'successful render.', { name: 'tester'});
}

definitions/middleware.js

var handler = require(F.path.definitions('handler'))

MIDDLEWARE('authorize',function($) {
    if($.controller.req.headers['x-token'] && $.controller.req.headers['x-token'] == '12345678') {
        $.next();    
    } else {
        handler.error($, 'Wrong header token!');
    }
});

Actualy I want to create a handler.js class, which is can be used in Controller, Middleware and Model Schema.

I know the problem is there is no $ in controller because self = this is already a controller object.

aalfiann commented 3 years ago

Thanks, I've have found the solutions, so I'll close this issue.