``Obtaining information from an Angular factory with the assistance of BreezeJs

Incorporating an Angular factory into my project has been a focus of mine lately.

Routing functionality has been successfully set up in ArtLogMain.js

var ArtLog = angular.module('ArtLog', ['ngGrid', 'ui.bootstrap']);

ArtLog.config(function ($locationProvider, $routeProvider) {
    $locationProvider.html5Mode(true);

    $routeProvider.when("/ArtLog", {
        controller: "ArtLogCtrl",
        templateUrl: "/Templates/ArtLog/Index.html"
    });

    $routeProvider.when("/ArtLog/:Id", {
        controller: "ArtLogEditCtrl",
        templateUrl: "/Templates/ArtLog/Edit.html"
    });

    $routeProvider.when("/ArtLog/Dashboard", {
        controller: "ArtLogDashBoardCtrl",
        templateUrl: "/Templates/ArtLog/Dashboard.html"
    });

    $routeProvider.otherwise("/");
});

Next step was to define the Factory: ArtLogDataService

ArtLog.factory("ArtLogDataService", function ($q) {
    breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);

    var _artLogView = [];
    var _artLogSingle = [];

    var _getArtLogById = function (Id) {

        var deferred = $q.defer();

        var manager = new breeze.EntityManager('breeze/BreezeData');
        var query = new breeze.EntityQuery().from('Project').where("Id", "Equals", Id);

        manager.executeQuery(query).then(function (data) {
            angular.copy(data, _artLogSingle);
            deferred.resolve();
        }).fail(function () {
            deferred.reject();
        });

        return deferred.promise;
    };

    var _getArtLogView = function () {

        var deferred = $q.defer();

        var manager = new breeze.EntityManager('breeze/BreezeData');
        var query = new breeze.EntityQuery().from('ArtLogView');

        manager.executeQuery(query).then(function (data) {
            //angular.copy(data.results, _artLogView);
            _artLogView = data.results;
            deferred.resolve();
        }).fail(function () {
            deferred.reject();
        });

        return deferred.promise;
    };

    return {
        artLogView: _artLogView,
        artLogSingle: _artLogSingle,
        getArtLogView: _getArtLogView,
        getArtLogById: _getArtLogById
    };
})

The Controller is defined as ArtLogController.js

function ArtLogCtrl($scope, ArtLogDataService) {
    $scope.ArtLogData = ArtLogDataService;
    $scope.editableInPopup = '<button id="editBtn" type="button" class="btn btn-primary" ng-click="edit(row)" >Edit</button>';

    ArtLogDataService.getArtLogView();

    $scope.edit = function (row) {
        window.location.href = '/ArtLog/' + row.entity.Id;
    };

    $scope.gridOptions = {
        data: ArtLogDataService.artLogView,
        showGroupPanel: true,
        enablePinning: true,
        showFilter: true,
        multiSelect: false,
        columnDefs: [
            { displayName: 'Edit', cellTemplate: $scope.editableInPopup, width: 80, pinned: true, groupable: false, sortable: false },
            { field: 'ArtNum', displayName: 'Art Number', resizable: true, pinned: true, groupable: false, width: '100px' },
            { field: 'CreateDate', displayName: 'Date Created', cellFilter: "date:'MM-dd-yyyy'", pinnable: false, width: '110px' },
            { field: 'ArtCompletionDue', displayName: 'Art Comp Due Date', cellFilter: "date:'MM-dd-yyyy'", pinnable: false, width: '160px', enableCellEdit: true },
            { field: 'DaysLeft', displayName: 'Days Left', pinnable: false, width: '90px' },
            { field: 'RevisionNum', displayName: 'Rev Number', pinnable: false, width: '100px' },
            { field: 'Status', displayName: 'Status', pinnable: false, width: '80px' },
            { field: 'Template', displayName: 'Template', pinnable: false, width: '190px' },
            { field: 'Driver', displayName: 'Driver', pinnable: false, width: '160px' },
            { field: 'AssignedTo', displayName: 'Assigned To', pinnable: false, width: '160px' },
            { field: 'BuddyArtist', displayName: 'Buddy Artist', pinnable: false, width: '160px' }
        ],
        filterOptions: {
            filterText: "",
            useExternalFilter: false
        }
    };
}

A debugging breakpoint on ArtLogDataService.getArtLogData shows that the call is triggered. The query runs and returns data, but for some reason, the data doesn't seem to bind to artLogView within the ArtLogDataService object returned from the factory.

Any insights would be greatly appreciated!

Answer №1

One issue is that the network callback from Breeze isn't synced with the Angular update loop. This means Angular doesn't recognize changes in your data, so the view binding watcher doesn't get updated.

To fix this, you should include a $scope.$apply() call when your data returns. This will prompt the bindings to acknowledge the data change and update accordingly.

You could try something like this:

ArtLogDataService.getArtLogView().then(function() {
    $scope.$apply();
});

If all actions are done within Angular, there's no need to manually call $scope.$apply, as Angular handles mutations (such as events, network responses, timeouts) through mechanisms like $http and

$timeout</code), automatically triggering <code>$apply
. It's only when external events impact data that $scope.$apply becomes necessary.

Hopefully, this resolves your issue!

Answer №2

Avoid using $q.deferred in query callbacks, stick to the promises returned by Breeze EntityManager methods. When utilizing the Breeze.Angular module as outlined in the documentation and shown in examples like "Todo-Angular", you already have access to $q promises.

Eliminate custom promises to remove the need for $apply.

Consider implementing code similar to this:

// Initialize or retrieve the manager ONCE throughout the data service's lifecycle
// For better testability, consider using a dedicated "entityManagerFactory" service
// to obtain your manager.
var manager = new breeze.EntityManager('breeze/BreezeData');

var _getArtLogView = function () {

    return breeze.EntityQuery.from('ArtLogView')
                 .using(manager).execute()
                 .then(success)
                 .catch(fail); // Use only if necessary to handle failures

    function success(data) { return data.results; }

    function fail(error) { 
       // Implement logging or relevant error handling;
       // Omit fail if not needed in this context
       return $q.reject(error); // Ensure caller is aware of the error
    }
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for adjusting the dimensions of my chart using JavaScript or Jquery

Utilizing DevExtreme widgets for the creation of a line chart in jQuery as shown below: var dataSource = [{"Date Range": "August-2018", Benelux: 194, Czech_Slovakia: 128, ...

Send the value to the <input> tag following each iteration in the functions

I am currently utilizing BootstrapVue. In my code, I have implemented a for loop to retrieve unique numbers from an array, which are stored as this.number. For each iteration of the loop, I use input.push() to add a new b-form-input element (in this case, ...

Trouble with Angular 1.6 ng-repeat not showing search results

I can't seem to figure out why ng-repeat is not showing the search results. Here's what works: Using an HTTP GET request to retrieve all data from the database, and seeing the results displayed by ng-repeat. Sending an HTTP GET request with ...

Choose an HTML <select> element and its <option> based on the presence of a specific string within its value

<select id='mySelect'> <option value='FirstOption'> Option 1 </option> <option value='SecondOption'> Option 2 </option> </select> I am attempting to automatically select the second option b ...

Using jQuery to drag a div and drop it to swap out an image in a different

I am looking to implement a drag and drop function where I can move elements from one div to another, each containing different images. However, I want the image displayed in the second div to change based on the element being dragged. For example: When d ...

Node: effectively managing SQL scripts with dynamic variable replacement

My SQL statements have grown quite large, and I want to store them as separate files with syntax highlighting. The solution I found on StackOverflow is perfect for my needs. In my case, I write SQL queries in JavaScript using Template Literal syntax for v ...

Instructions for showing a timer on a webpage from a managed bean by utilizing JavaScript

I'm currently tackling the challenge of passing a Date from a managed bean to JavaScript and then displaying it as a timer in the format "hh:mm:ss aa". I've attempted it but so far, no luck. Code: DateTimeManagmentMB.java (Managed Bean) import ...

Having difficulty finding the element in Selenium WebDriver while using C#

Can anyone help me locate the element in the following HTML tag? I keep getting an exception: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id='divMain']/div/app-train-list/div ...

Tips for resolving the strange behavior on a webpage with multiple active buttons labeled "portfolio"

I'm currently dealing with an issue regarding the behavior of a particular webpage that is quite unusual. I have provided a link to the Github page where this issue is occurring. Interestingly, the problem seems to be resolved when I remove the nav ta ...

Unable to locate JavaScript files within the Django project

I utilized Python 3.7 on Windows 10 to develop a Django project. settings.py: STATIC_URL = '/static/' LOGIN_URL = '/login' LOGIN_REDIRECT_URL = '/' https://i.sstatic.net/LSAdq.png I employed superuser to create some regu ...

What is the best way to retrieve the errors recorded property from a customized input component that has been validated with vee-validate?

I am currently exploring the use of VeeValidate within a custom input component. In my attempts, I have experimented with using $emit on both @input and @blur events. However, I have encountered an issue where validation takes place in the next tick, caus ...

What is the best way to toggle dropdown menu items using jQuery?

Upon clicking on an li, the dropdown menu associated with it slides down. If another adjacent li is clicked, its drop down menu will slide down while the previous one slides back up. However, if I click on the same li to open and close it, the drop down m ...

What is the process for generating a default template when the web directory's URL is accessed?

Within my AngularJS project, I have organized common components and services into separate folders such as root/component/ and root/services/. When I navigate to the URL "root/component/" in my browser, a webpage is displayed showing all subfolders and fil ...

Using Module.Controller() syntax within AngularJS UI Bootstrap 0.6.0 Modal for enhanced functionality

When it comes to defining the controller for my modal instance, I am looking to make a change. Instead of using the traditional method like this: var ModalInstanceCtrl = function ($scope, $modalInstance, items) { /*ctrl-code-here*/ }; I would prefer to u ...

How to detect the Back Button or Forward Button events in a single-page application

Currently, I am developing a single-page application that utilizes ASP.NET MVC, Backbone.js, and JQuery. My task involves capturing the browser's back and forward button events for breadcrumb implementation. I previously attempted to use the hashchan ...

What are the steps to switch multiple CSS styles for creating a dark mode?

I'm currently using a combination of HTML, CSS, and JavaScript to construct my website. One feature I'd like to implement is a Darkmode switch button that toggles between Dark and Light mode when clicked. However, the issue I'm facing is tha ...

Instance lacks ES6 class method

I am currently revamping my existing node.js project to incorporate ES6 features as part of the preparation for migrating to typescript. However, I am facing an issue with a particular class that I've defined in a separate file: class Database { con ...

Revisiting Dynamic URL Parameters with React Router and Express

After setting up my React router to navigate '/Article/1/' via a link, everything seems to be working fine. However, I encountered an issue when refreshing the browser as it no longer detects my Article component. MainApp.js import React from & ...

When calling canvas.getContext('2D'), the function returns a null value

After creating a canvas and calling its getContext() method, I was confused when it returned null for the context. Below is the code snippet that I used: <script> window.onload = initializeCanvas; function initializeCanvas(){ ...

CKEditor is completely altering the format of my HTML code

Dealing with CKEditor has been a real challenge for me all day long. It seems to be reformatting my HTML code without any rhyme or reason. I've noticed that it's replacing certain tags like <dl> with <div> and <p>. To tackle thi ...