Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Erro no exercício

Retornei a aplicação ao estado anterior ao exercício. Funcionou corretamente. Ao fazer as alterações acusa esse erro. Não entendo o que estou deixando passar.

Uncaught TypeError: Cannot read property 'map' of undefined
    at NegociacoesView.template (NegociacoesView.js:34)
    at NegociacoesView.update (View.js:12)
    at new NegociacaoController (NegociacaoController.js:26)
    at index.html:61
template @ NegociacoesView.js:34
update @ View.js:12
NegociacaoController @ NegociacaoController.js:26
(anonymous) @ index.html:61

classe NegociacoesView


class NegociacoesView extends View {

    template(model) {

        return `
        <table class="table table-hover table-bordered">
            <thead>
                <tr>
                    <th>DATA</th>                       
                    <th>QUANTIDADE</th>
                    <th>VALOR</th>
                    <th>VOLUME</th>
                </tr>
            </thead>

            <tbody>
                ${model.negociacoes.map(n => {  //< linha 34 é aqui
                    return `
                        <tr>
                            <td>${DateHelper.dataParaTexto(n.data)}</td>
                            <td>${n.quantidade}</td>
                            <td>${n.valor}</td>
                            <td>${n.volume}</td>
                        </tr>
                    `
                }).join('')}
            </tbody>

            <tfoot>
                <td colspan="3"></td>
                <td>
                    ${model.negociacoes.reduce((total, n) => total + n.volume,0.0)}
                </td>
            </tfoot>
        </table>
        `;  
    }
}

Controlador

/**
 * classe que faz o controle dos inputs no formulário
 */

class NegociacaoController {

    constructor() {


        let $ = document.querySelector.bind(document);

        this._inputData = $('#data');
        this._inputQuantidade = $('#quantidade');
        this._inputValor = $('#valor');

        let self = this;

        this._listaNegociacoes = ProxyFactory.create(
            new ListaNegociacoes(),
            ['adiciona','esvazia'], model => 
            this._negociacoesView.update(model));

        this._negociacoesView = new NegociacoesView($('#negociacoesView')); // instanciando a view
        this._negociacoesView.update(this._listaNegociacoes);

        this._mensagem = ProxyFactory.create(
            new Mensagem(),
            ['texto'], model => 
            this._mensagemView.update(model));

        this._mensagemView = new MensagemView($('#mensagemView'));
        this._mensagemView.update(this._mensagem);




    }

    // método que faz a submissão do formulario
    adiciona(event) {

        event.preventDefault();

        this._listaNegociacoes.adiciona(this._criaNegociacao());


        this._mensagem.texto = 'Negociação adicionada com sucesso';



        this._limpaFormulario();

    }

    _criaNegociacao() {
        return new Negociacao(
            DateHelper.textoParaData(this._inputData.value),
            this._inputQuantidade.value,
            this._inputValor.value
        );
    }

    _limpaFormulario() {
        this._inputData.value = '';
        this._inputQuantidade.value = 1;
        this._inputValor.value = 0.0;

        this._inputData.focus();
    }

    apaga() {
        this._listaNegociacoes.esvazia();
        this._mensagem.texto = 'Negociações apagadas com sucesso';

    }
}
7 respostas

Olá, Geovane.

Como está sua classe View?

class View {

    constructor(elemento) {
        this._elemento = elemento;
    }

    template() {
        throw new Error('O método template deve ser implementado!');
    }

    update(model) {
        this._elemento.innerHTML = this.template(model);
    }
}

A única classe que foi alterada foi o controlador.

Estranho, Geovane!

O erro foi:

Uncaught TypeError: Cannot read property 'map' of undefined

Isso acontece quando você tenta invocar o map de algo que está undefined.

Na linha 34, você faz:

${model.negociacoes.map ( ... ) }

Portanto, o atributo negociacoes de model está undefined.

Esse atributo vem da chamada do update da View:

 update(model) {
        this._elemento.innerHTML = this.template(model);
    }

O update de NegociacoesView é chamado nesse trecho do NegociacaoController:

     this._listaNegociacoes = ProxyFactory.create(
            new ListaNegociacoes(),
            ['adiciona','esvazia'], model => 
            this._negociacoesView.update(model));

        this._negociacoesView = new NegociacoesView($('#negociacoesView'));
        this._negociacoesView.update(this._listaNegociacoes);

O model virá do código de ProxyFactory, no get:

acao(target);

Esse código de ProxyFactory, invoca a lambda.

Será que você esqueceu de passar o target?

Não tenho certeza, mas acho que não.

class ProxyFactory {

    static create(objeto, props, acao) {

        return new Proxy(objeto, {

            get(target, prop,receiver) {
                if(props.includes(prop) && typeof(target[prop]) == typeof(Function)) {

                    return function() {
                        console.log(`a propriedade "${prop}" foi interceptada`);
                        Reflect.apply(target[prop], target, arguments);
                        return acao(target);

                    }
                    return Reflect.get(target, prop, receiver);
                }
            }
        });
    }
}
solução!

Olá, Geovane.

Acho que faltou retornar o retorno do Reflect.apply.

Seu código está assim:

Reflect.apply(target[prop], target, arguments);
return acao(target);

Nesse trecho, o código do instrutor Flávio está assim:

let retorno = Reflect.apply(target[prop], target, arguments);
acao(target);
return retorno;

okay vou tentar

Era esse o problema mesmo!

let retorno = Reflect.apply(target[prop], target, arguments);
acao(target);
return retorno;