0

I have problem with below code. I have prices factory which returns object containing prices received from server by websocket. Prices are sent after button Create is clicked. Problem is that main.prices variable is not updated at all. I can check everything by Check button, which confirms this. Prices.data is updated, but this.prices is not, but it refers the same object, so I thought it should be updated as well. Do you have any ideas why below does not work as expected?

angular.module('myApp', ['ngWebSocket'])

    .factory('ws', ['$websocket', function($websocket){
        var url = 'ws://localhost/websocket';
        var ws = $websocket(url);        
        return ws;
    }])

    .factory('prices', ['ws', function(ws){
        var prices = {
            data: [],
            clear: function(){
                this.data = [];
            },
            create: function(){
                ws.send('send')
            }
        }

        ws.onMessage(function(message){
            message = JSON.parse(message.data);
            var type = message.type;

            if (type == 'new prices'){               
                prices.data = message.data;
            }
        });

        return prices;
    }])

    .controller('main', ['prices', function(prices){
        this.prices = prices.data;

        this.check = function(){
            console.log('works ', prices.data);
            console.log('not works ', this.prices);
        };

        this.create = function(){
            prices.create();
        };

        this.stop = function(){
            prices.clear();
        };
    }]);

<div ng-controller="main as main">
    {{ main.prices }}
    <button ng-click="main.create()">Create</button>
    <button ng-click="main.stop()">Stop</button>
    <button ng-click="main.check()">Check</button>
</div>
1
  • Your dealing with reference issues. Commented Jun 16, 2015 at 14:24

2 Answers 2

2

There are a lot of issues with the code you posted (working on a fiddle so i can help rework it) ...

First change :

if (type == 'new prices'){               
    prices.data = message.data;
}

To:

if (type == 'new prices'){   
    prices.data.length = 0;            
    prices.data.push.apply(prices.data,message.data) ;//copy all items to the array.
}

From a readability / maintainability point of view you should just use this.prices vs this.prices.data. It's confusing to map them to other variables, when you can just use prices. Also note that I updated it to use "that" constantly to avoid any type of context this issues.

.controller('main', ['prices', function(prices){
    var that = this;
    that.prices = prices;

    that.check = check;
    that.create = create; 
    that.stop = stop;

    function check(){
        console.log('works ', that.prices.data);
        console.log('not works ', that.prices);
    }

    function create(){
        that.prices.create();
    }
    function stop(){
        that.prices.clear();
    }
}]);
Sign up to request clarification or add additional context in comments.

1 Comment

Ok thank you for your help. I was creating new object while controller variable refered to the new one :) I needed also to change clear function to this.data.length = 0 - the same mistake :)
1

To add to the previous response, you also have an issue on the clear():

var prices = {
    ...
    clear: function(){
        this.data = [];
    },
    ...
}

when you do the clear with this.data = [] you are actually creating a new empty array an storing that in the this.data prop, and since this is a NEW array, the reference on main controller -> this.prices = prices.data; is still pointing to the old one. If you need to delete elements on the array just use this.data.length = 0 as Nix pointed out for the other method. that will keep all references in sync since you are re using the original array

1 Comment

oops, just after posting this i saw you added a comment on the other response

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.