In my recent project, I encountered a complex issue while implementing a file download feature for a document management system. The file download process required integration between an AngularJS frontend and a Java Spring Boot backend, with files stored dynamically on the server. Outcome, when a link/button is clicked, it able to auto download inside local pc & able to successfully open the downloaded file: Challenges: When attempting to download files, I encountered various issues: 1. File Not Downloading Properly: Initial attempts to download files led to corrupted or unopenable files. 2. Dynamic Path Handling: The backend stored files in a specific directory, requiring a way to build the correct URL dynamically from AngularJS. 3. Browser Compatibility & Blob Usage: Some methods for file downloading worked inconsistently across browsers or introduced compatibility issues. 4. Need to follow a standardized Angular JS' $resource for making the backend calls to fetch files while dynamically building the download URL. Solution: 1. Dynamic File Path Resolution in Java: I configured the Java backend to handle file paths using This allowed the backend to access files from a specified directory dynamically based on user input. 2. AngularJS Fetching with > What I mean by this is, this project has standardized to call the fetch API method using a service called FormService when it utilizes the Angular's $resource: angular.module('app').factory('FormService', ['$resource', function($resource, $routeParams) { //http://localhost:9090/api/../../.. var uparams = {modulecode: '@modulecode',caseid: '@caseid', version: '@version', p:'@p', action: '@action', id: '@id', mode: '@mode', process: '@process', taskid: '@taskid', filename: '@filename', filter: '@filter', type: '@type', module: '@module'} return $resource(':url', uparams, { This function is then called inside the Angular controller as I have describe in step part no.3 below. 3. Frontend Download Handling: I set up a > It involves with an HTML <a> element to trigger the download, allowing me to handle the download dynamically and with minimal compatibility issues. Here's the example of how I've implemented this: $scope.downloadFile = function(letterfilename) { if (!letterfilename) { ciWarn("", "No filename provided for download."); return; } // Define the download URL based on backend path and filename const downloadUrl = $scope.baseUrl + '/api/docs/' + encodeURIComponent(letterfilename); // Call FormService to fetch the file using $resource FormService.downloadLetterFile({ filename: letterfilename }, function(response) { if (response) { // Create a temporary <a> element to trigger the download const link = document.createElement('a'); link.href = downloadUrl; // Set the URL for the file link.download = letterfilename; // Set the download attribute for filename document.body.appendChild(link); // Append to DOM temporarily link.click(); // Trigger download document.body.removeChild(link); // Clean up by removing the link } else { ciWarn("", "File not found on the server."); } }, function(error) { console.error("Error downloading file:", error); ciWarn("", "Unable to download file due to a network error."); }); };Path filePath = Paths.get("path/directory").resolve(filename).normalize();
$resource
: Instead of using direct $http
requests, I utilized $resource
for consistency with other service calls, allowing smoother data fetching and handling response data more flexibly.fetch
API fallback, along with AngularJS $resource
functions, to handle the file download with checks for response validity and cross-browser compatibility.
0 Comment(s)
The tags introduced in HTML5 are more descriptive such as: main, header, footer, nav, video, article, section, audio & many more. These tags helps with Search Engine Optimization (SEO) and accessibility. The main tag helps search engine and other developers find the main content of your page. Adding an image to your page: Link to external pages:
0 Comment(s)
0 Comment(s)
1. Connect Web Worker to SQL Database. Web worker does not allow default JQUERY to be used. Alternatives:
0 Comment(s)
1. Please refer to this post to display data in table 2. After displaying them in the table, follow the instructions attached on the comment section (//): //determine no of data to display per page $results_per_page = 10; //count all column from the database $sql = "SELECT COUNT(*) FROM test_user"; $res = $dbx->query($sql); $count = $res->fetchColumn(); // determine no of total pagination needed by dividing no of total columns ($count) with total data to display (10) $number_of_pages = ceil($count/$results_per_page); // determine which page number visitor is currently on if(!isset($_GET['page'])){ $page = 1; }else{ $page = $_GET['page']; } // determine the sql LIMIT starting number for the results on the displaying page $this_page_first_result = ($page-1)*$results_per_page; $sql = "SELECT id, user_email, user_fullname, user_address, user_city, user_zip, user_state, user_country, user_tel, user_fax from test_user LIMIT ". $this_page_first_result . "," .$results_per_page; $result = $dbx->query($sql); // if result is not zero, display result if($result-> rowCount() > 0){ while($row = $result-> fetch(PDO::FETCH_ASSOC)){ echo "<tr><td>".$row["id"]."</td><td>" .$row["user_email"] . "</td><td>" .$row["user_fullname"]."</td><td>" .$row["user_address"]."</td><td>" .$row["user_city"]."</td><td>" .$row["user_zip"]."</td><td>" .$row["user_state"]."</td><td>" .$row["user_country"]."</td><td>" .$row["user_tel"]."</td><td>" .$row["user_fax"]."</td></tr>"; } echo "</table>"; } // if result is zero, display 0 result else{ echo "0 result"; } // loop: define $page = 1, as long as $page less or equal to $number_of_pages, increase $page ((in this case, it is: 1,2,3)) // in the loop, echo the pagination style you want to display. in this case, I use the one in Bootstrap 5 Pagination for($page=1; $page<=$number_of_pages; $page++){ echo '<ul class="pagination pagination-sm"> <li> <span class="page-link"><a href="display-data.php?page='. $page. '">' . $page. '</a></span> </li>'; }
0 Comment(s)
0 Comment(s)
Android Studio problem [SOLVED]: [1] Error Inflate XML in activity Solution 1: 1. Remove <fragment tag from activity xml 2. Rather, replace it with a <FrameLayout 3. In activity class, simply setContentView(R.layout.fragment_register); //here, set the layout as the fragment id Solution 2 (turns out my error is actually this) 1. Check the fragment class 2. My error was I did not inflate the fragment class ------------ *note: any button or function should be made inside onViewCreated [2] Error public void onComplete(@NonNull Task<AuthResult> task) { not succesful Solution: 1. Add "uses INTERNET" in androidmanifest.xml 2. Make sure all variables in class User are accesible (make them public) [3] Attempt to invoke virtual method 'void androidx.navigation.NavController.navigate(int)' on a null object reference Solution: 1. Change navigate method from: navController.navigate(R.id.action_registerFragment2_to_logIn); to: Navigation.findNavController(v).navigate(R.id.action_registerFragment2_to_logIn);
0 Comment(s)