Why is my Angular ng-model composite value not updating?

I haven’t used JavaScript in six years, so I’m brushing up on it and learning Angular at the same time via W3Schools. This means I’m likely doing multiple things wrong here, so bear with me.

In my code below, I would expect that rgb would update to the composite of red, green, and blue as I move the input sliders. However, the DIV with background: #{{rgb}}; doesn’t render at all, so it’s obviously unhappy.

Full code:

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<head>
<title>Color Mixer</title>
<style>
.slider {
    -webkit-appearance: none;
    width: 255px;
    height: 25px;
    outline: none;
    opacity: 0.7;
    -webkit-transition: .2s;
    transition: opacity .2s;
}

.slider:hover {
    opacity: 1;
}

.slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 25px;
    height: 25px;
    background: #000000;
    cursor: pointer;
}

.slider::-moz-range-thumb {
    width: 25px;
    height: 25px;
    background: #000000;
    cursor: pointer;
}
</style>
</head>

<body style="font-family: verdana;">

<div ng-app="app" ng-controller="controller">
    <h1>Color Mixer</h1>
    <input type="range" min="0" max="255" value="128" class="slider" style="background: #880000;" ng-model="red"></br>
    <input type="range" min="0" max="255" value="128" class="slider" style="background: #008800;" ng-model="green"></br>
    <input type="range" min="0" max="255" value="128" class="slider" style="background: #000088;" ng-model="blue"></br>

    <div style="width: 256px; height: 25px; margin: 1px; text-align: center;" ng-model="rgb">
        {{
            red.toString(16).toUpperCase().padStart(2, "0") +
            green.toString(16).toUpperCase().padStart(2, "0") +
            blue.toString(16).toUpperCase().padStart(2, "0")
        }}
    </div>

    <div style="width: 256px; height: 256px; margin: 1px; background: #{{rgb}};">
    </div>

    <div style="width: 256px; height: 256px; margin: 1px; background: #{{red.toString(16).toUpperCase().padStart(2, "0") + green.toString(16).toUpperCase().padStart(2, "0") + blue.toString(16).toUpperCase().padStart(2, "0")}};">
    </div>
</div>

</body>

<script>
var app = angular.module('app', []);
app.controller('controller', function($scope) {
});
</script>

</html>

You can see that I also added a second attempt at a background-colored DIV using padStart() with character-escaped double-quotes; it also does not render.

Finally, I added the controller even though it’s empty. I tried assigning the value of rgb there, but it wouldn’t let me access red, green, or blue.

Why is my Angular ng-model composite value (rgb) not updating?

Answer

ng-model will not work with divs and style syntax on the other divs is invalid.

You could use ng-style to achieve what you want with rgb values:

ng-style="{ 'background-color': 'rgb('+red+', '+green+', '+blue+')' }"

Check here a working demo: DEMO