I consider my database quite well nested. And for each data I saved it using the current user uid, then I push it into firebase which it create a unique pushid, so when I want to get the data, it always just get one data which is not from the unique pushid, but the user uid is correct. How do I get the correct data from the correct pushid?
My database that I want to save the information: https://imgur.com/a/tird0jD
My database that I retrieve the information that I want to save in the other node of the database: https://imgur.com/a/50f1M8W
As you notice in the picture of the database, the uid and pushid are retrieve correctly, but the data inside is retrieve wrongly and when I try for all, it seems to be returning all the same data.
Below is my JS code:
function choose() {
assign(document.getElementById("updateUserID").value, document.getElementById("updateID").value,
document.getElementById("person").value);
}
var rootRef2 = firebase.database().ref('Admin/Person In Charge/Towing');
select = document.getElementById('person');
var opt1 = document.createElement('Option');
opt1.value = "-Select-";
opt1.innerHTML = "-Select-";
select.appendChild(opt1);
//Retrieve P-I-C data from Firebase
rootRef2.on("child_added", function (pericRecord) {
var opt = document.createElement('Option');
opt.value = pericRecord.val().Name;
opt.innerHTML = pericRecord.val().Name;
select.appendChild(opt);
});
function showModal(userId, pushId) {
$('#modal').modal("show");
document.getElementById("updateID").value = pushId;
document.getElementById("updateUserID").value = userId;
}
function assign(userId, pushId, x) {
var person = x;
var rootRef3 = firebase.database().ref('Users/Towing Request/' + userId)
rootRef3.on('child_added', function (snapshot) {
document.getElementById("updateID").value = pushId;
document.getElementById("updateUserID").value = userId;
firebase.database().ref('Admin/AssignCarTowing/' + person +"/"+userId +"/"+pushId)
.update({
CustUID: userId,
CustName: snapshot.val().Name,
CustCarModel: snapshot.val().CarModel,
CustCarNumber: snapshot.val().CarNumber,
CustContactNo: snapshot.val().ContactNo,
CustLocation: snapshot.val().BreakdownLocation,
CustBDTD: snapshot.val().TowingDateandTime
})
});
firebase.database().ref('/Users/Towing Request/' + userId + "/" + pushId)
.update({ PersonInCharge: person, Status: "Assigned" });
window.alert("Updated to Assigned with Person In Charge");
firebase.database().ref('/Users/Towing Request/' + userId + "/" + pushId).once('value').then(function (snapshot) {
//document.getElementById('name').value = snapshot.val().Name;
//document.getElementById('email').value = snapshot.val().Email;
//document.getElementById('peric').value = snapshot.val().PersonInCharge;
//document.getElementById('status').value = snapshot.val().Status;
window.alert("Retrieved");
location.reload();
});
}
My html code where I choose who to save into:
<div class="modal fade" id="modal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Choose Person In Charge</h4>
</div>
<div class="modal-body">
<input type="text" id="updateID" />
<input type="text" id="updateUserID" />
<select id="person" onchange=choose()>
</select>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
I tried every possible answer from all the searches I got, but still no luck.
I manage to solve this myself by trial and error of the code. Below is the code that help me to solve this problem.
function assign(userId, pushId, person) {
var rootRef3 = firebase.database().ref('Users/Towing Request/' + userId);
rootRef3.on('value', function (snapshot) {
console.log(snapshot.key)
firebase.database().ref('Admin/AssignCarTowing/' + person + "/" + userId + "/" + pushId)
.set({
CustUID: userId,
CustName: snapshot.child(pushId).val().Name,
CustCarModel: snapshot.child(pushId).val().CarModel,
CustCarNumber: snapshot.child(pushId).val().CarNumber,
CustContactNo: snapshot.child(pushId).val().ContactNo,
CustLocation: snapshot.child(pushId).val().BreakdownLocation,
CustBDTD: snapshot.child(pushId).val().TowingDateandTime
})
});
firebase.database().ref('/Users/Towing Request/' + userId + "/" + pushId)
.update({ PersonInCharge: person, Status: "Assigned" });
window.alert("Updated to Assigned with Person In Charge");
location.reload();
}
Only the function Assign, is changed.
Related
Before this gets marked as a duplicate, please note that I've found a solution, but it's not working for me.
I'm making a web app that allows a user to log in, do a search for a movie, and then select a movie from the search results to add it to a 'wish list' that's associated with that user. My only background in web development is a Udemy course that I just finished, and this is the first project I've worked on independentaly.
I've got an ejs file that renders the search page. Here's a snippet of that file:
<%- include("./partials/header.ejs") %>
<div class="container">
<h1 class="text-center"> Create new Request for <em><strong><%= currentUser.username %></strong></em> </h1>
<div class="row justify-content-center">
<div class="col-12 col-lg-4">
<input id="search_box" class="form-control" type="text" name="title" placeholder="Movie Title">
<button id="search_button" class="btn btn-primary btn-block">Search</a>
</div>
</div>
<div id="results" class="row">
<h3> Results... </h3>
<div class="card mb-3">
<div class="row no-gutters">
<div class="col-lg-4">
<img id="poster_0" class="card-img" src="#" alt="Card image cap">
</div>
<div class="col-lg-8">
<div class="card-body">
<h5 id="movie-title_0" class="card-title"><strong>Batman Begins</strong> - <em>1984</em></h5>
<p class="card-text"><strong>Description</strong>:
<span id="movie-description_0">
</span>
</p>
<p class="card-text"><strong>IMDB Rating</strong>:
<span id="movie-rating_0">
</span>
</p>
<a id="add_button_0" href="#" class="btn btn-primary">Add to Requests</a>
........
</div>
</div>
<script src="/javascripts/apikey.js"></script>
<script src="/javascripts/search.js" currentUserId=<%= currentUser._id %> currentUserName=<%= currentUser.username %>></script>
<%- include("./partials/footer.ejs") %>
In the included script at the bottonm, I create an array of movie objects based on what's returned by TMDB. Here's the code from the script:
let baseURL = 'https://api.themoviedb.org/3/';
let configData = null;
let baseImageUrl = null;
let movieData = [];
let currentUserId = document.currentScript.getAttribute("currentUserId");
let currentUserName = document.currentScript.getAttribute("currentUserName");
let getConfig = function() {
let url = ''.concat(baseURL, 'configuration?api_key=', API_KEY);
fetch(url)
.then((result) => {
return result.json();
})
.then((data) => {
baseImageUrl = data.images.secure_base_url + data.images.poster_sizes[3];
configData = data.images;
console.log('config:', data);
console.log('config fetched');
})
.catch((err) => {
alert(err);
});
}
let runSearch = function(keyword) {
let url = ''.concat(baseURL, 'search/movie?api_key=', API_KEY, '&query=', keyword);
console.log("Keyword is: " + keyword);
console.log(url);
fetch(url)
.then((result) => {
return result.json();
})
.then((data) => {
for (let i = 0; i < 3; ++i) {
movieData[i] = {
movie_id: data.results[i].id,
movie_title: data.results[i].title,
movie_release_date: data.results[i].release_date,
movie_description: data.results[i].overview,
movie_rating: data.results[i].vote_average
};
document.querySelector("#results").style.visibility = 'visible';
document.querySelector("#poster_" + i).src = baseImageUrl + data.results[i].poster_path;
document.querySelector("#movie-title_" + i).innerHTML = "<strong>" + data.results[i].title + "</strong> - <em>" + data.results[i].release_date + "</em>";
document.querySelector("#movie-description_" + i).textContent = data.results[i].overview;
document.querySelector("#movie-rating_" + i).textContent = data.results[i].vote_average;
}
console.log(JSON.stringify(movieData));
});
}
document.addEventListener('DOMContentLoaded', getConfig);
console.log("The current user is: " + currentUserName + " - Id:" + currentUserId);
document.querySelector("#search_button").addEventListener('click', (e) => {
runSearch(document.querySelector("#search_box").value);
});
=================> MOST RELAVENT BIT BELOW <===============
for (let i = 0; i < 3; ++i) {
document.querySelector("#add_button_" + i).addEventListener('click', (e) => {
console.log("TEST OUTPUT: " + JSON.stringify(movieData[i]));
var xhr = new XMLHttpRequest();
var postUrl = "/users/" + currentUserId + "/requests/new";
xhr.open("POST", postUrl, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(JSON.stringify(movieData[i]));
});
}
When the 'add to requests' button is clicked, what should happen is that the data in movieData[i] gets converted to a string, and sent as a post request to /users/id/requests/new. Here are my route definitions:
const express = require('express');
const router = express.Router();
const middleware = require("../middleware/auth.js");
const User = require("../models/user.js");
/* GET users listing. */
router.get('/', (req, res) => {
res.send('respond with a resource');
});
router.get('/id/requests', (req, res) => {
res.render('../views/requests', {title: "Profile - Groovie"});
});
router.get('/id/requests/new', (req, res) => {
res.render('../views/new', {title: "New Request - Groovie"})
})
router.post('/:id/requests/new', (req, res) => {
console.log(req.body);
User.findById(req.params.id, (err, user) => {
if (err) {
console.log(err);
} else {
user.requested_movies.push({
movie_id: req.body.movie_id,
movie_title: req.body.movie_title,
movie_release_date: req.body.movie_release_date,
movie_description: req.body.movie_description,
movie_rating: req.body.movie_rating
});
console.log("Added movie " + req.body.movie_title);
user.save();
}
});
});
module.exports = router;
So here we have our problem: All of the data that's getting pushed to the User object is blank. The console.log(req.body) is showing me that there is some kind of error in the way that the post request is getting parsed. Here's what's getting output:
{
`{"movie_id":320288,"movie_title":"Dark Phoenix","movie_release_date":"2019-06-05","movie_description":"The X-Men face their most formidable and powerful foe when one of their own, Jean Grey, starts to spiral out of control. During a rescue mission in outer space, Jean is nearly killed when she's hit by a mysterious cosmic force. Once she returns home, this force not only makes her infinitely more powerful, but far more unstable. The X-Men must now band together to save her soul and battle aliens that want to use Grey's new abilities to rule the galaxy.","movie_rating":6}`: ''
}
It took me forever to spot this, but I think that what's happening is that, instead of parsing each key-value pair as a key-value pair, the route is parsing the entire string as a single key, and the value is ''
Even if I take out the JSON.stringify bit from within the XMLHttpRequest.send() call and manually add a string like "number_of_dogs: 14, number_of_cats: 3", the same weird parsing takes place. The console.log from within the route definition prints out {"<whatever string was passed>" : ''}
I'm not married to the XmlHttpRequest method for getting the data to the new route, that's just the solution I found here. The course I took only really talked about making post requests via forms. Any guidance would be enormously appreciated.
The relevant Javascript follows below, but in short, the archive button works while the delete button does not. I've already tried moving the event handler to a different file which the HTML calls using script tags to see if that makes a difference, but it doesn't seem to, although I'm unsure if it's broken in the same way. Additionally, the actual functions associated with each event handler are practically the same, so it seems reasonable to rule out that the function itself causes the problem. Why are the two buttons performing differently?
const mongo = require('mongodb');
const config = require('../../javascripts/config.js'); //databaseAddress can now be found at config.databaseAddress()const mongo = require('mongodb');
const MongoClient = mongo.MongoClient;
const url = config.databaseAddress();
$(document).ready(function () {
$('#navbar-userSearch').addClass('active');
$('.archive-button').click(function () {
var id = $(this).attr('id').split('-').slice(-1)[0] ;
console.log('id', id);
var username = $('#username-' + id).val();
var csrf = $('#csrf').val();
var action = $(this).attr('id').split('-')[0];
console.log('username', username);
$.ajax({
url: '/'+action+'/'+username,
type: 'PUT',
data: {username: username, _csrf: csrf},
success: function(data) {
if (data.success) {
addMessage(data.message, true);
if (typeof data.redirect === 'string') {
setTimeout(function(){
window.location = data.redirect;
}, 2500);
}
} else {
addMessage(data.message, false);
}
},
error: function(err) {
addMessage('A network error might have occurred. Please try again.', false);
}
});
});
$('.delete-button').click(function() {
console.log("stop pushing my buttons");
var id = $(this).attr('id').split('-').slice(-1)[0] ;
console.log('id', id);
var username = $('#username-' + id).val();
console.log('username', username);
MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => {
const db = client.db("paxpopulidb");
const id_query = {_id: id};
const username_query = db.collection("users").find(id_query, {_id: 0, username: 1});
const username = username_query.username;
if (username) {
if (username === "superadmin"){
console.log("You cannot delete the superadmin account.");
} else {
db.collection("registrations").deleteOne(username_query);
db.collection("users").deleteOne(username_query);
db.collection("schedules").deleteOne(username_query);
console.log("Deleted " + username + " from database.");
}}})
})});
The HTML uses Handlebars for templating and is as follows:
{{#each users}}
<div class='col-xs-12 col-ms-6 col-sm-4 col-md-3 col-lg-4 user-container tile-container' id='user-container-{{_id}}'>
<div class='tile user-tile' name="user-{{_id}}" data-id='{{_id}}'>
<div class='tile-icon' style='float: left'><img class='icon' src="/images/user.gif"></img></div>
<div class='user-header tile-header'>
<a data-toggle="modal" data-target='#user-modal-{{_id}}'>
<h4 class='tile-title'>{{#if fullName}}{{fullName}}{{else}}{{firstName}} {{lastName}}{{/if}}</h4>
</a>
<p class='tile-subtitle'>{{role}}<h class='small-text'>{{#if archived}}(archived){{/if}}</h></p>
</div>
</div>
<div id="user-modal-{{_id}}" class="user-item-modal modal fade" role="dialog">
<div class="modal-messages"></div>
<div class="modal-dialog modal-xs">
<div class="modal-content">
<div class="modal-header modal-title">
<button type="button" class="close" data-dismiss="modal">×</button>
{{#if fullName}}{{fullName}}{{else}}{{firstName}} {{lastName}}{{/if}}'s Profile
</div>
<div class="modal-body">
{{> profileTable}}
</div>
</div>
</div>
</div>
<div>
<input id='username-{{_id}}' type="hidden" value="{{username}}"></input>
<input id='requestToken-{{_id}}' type="hidden" value="{{requestToken}}"></input>
<input id='csrf' type="hidden" name="_csrf" value="{{csrfToken}}">
<center>
{{#isRegularUser role}}
<button id='registration-button-{{_id}}' class='btn btn-info btn-hg registration-button'>View/Edit Registration</button>
<button id='schedule-button-{{_id}}' class='btn btn-info btn-hg schedule-button'>View/Edit Schedule</button>
{{/isRegularUser}}
{{#ifNot archived}}
<button id='archive-button-{{_id}}' class='btn btn-warning btn-hg archive-button'>Deactivate</button>
{{else}}
{{/ifNot}}
{{#isRegularUser role}}
<button id='delete-button-{{_id}}' class='btn btn-danger btn-hg delete-button'>Delete User</button>
{{/isRegularUser}}
</center>
</div>
</div>
{{/each}}
In short, the above makes a small box with appropriate buttons for each user depending on their role attribute, but the only working button so far is archive-button (no event handlers exist for the other two yet) However, the delete-button actually displays, it's just that clicking it does nothing.
Your bracketing is wrong. You have the delete button event handler inside the archive button click handler. So the delete handler isn't added until you click on an archive button (and if you click on archive multiple times, the delete buttons will execute their code multiple times).
You would see this if you'd indented your code correctly (every programming editor has options to automate this for you).
It should be:
$(document).ready(function() {
$('#navbar-userSearch').addClass('active');
$('.archive-button').click(function() {
var id = $(this).attr('id').split('-').slice(-1)[0];
console.log('id', id);
var username = $('#username-' + id).val();
var csrf = $('#csrf').val();
var action = $(this).attr('id').split('-')[0];
console.log('username', username);
});
$('.delete-button').click(function() {
console.log("stop pushing my buttons");
var id = $(this).attr('id').split('-').slice(-1)[0];
console.log('id', id);
var username = $('#username-' + id).val();
console.log('username', username);
});
});
I'm trying to join the data result from ajax to the const res.
So Ideally the list order would be
Attack 402983
Defense 1500
Strength 70
HitPoints 68
As you can see below, i'm having trouble appending the two together in a list fashion. An example of whats coming from ajax data is 402983,1500,70,68
HTML
<form class="form-inline mt-2 mt-md-0">
<input class="form-control mr-sm-2" type="text" name="search" placeholder="Search"/>
<button id="search-btn" class="btn btn-outline-success my-2 my-sm-0" type="submit">Search </button>
</form>
<ul id="response">
</ul>
JAVASCRIPT
// this is the id of the form
$('#search-btn').on('click', function(e) {
e.preventDefault();
var url = "?player=";
var player = $('input[name="search"]').val();
var urlAddition = url + player
$.ajax({
url: urlAddition,
dataType: "html",
success: function(data) {
const res = 'Attack, Defense, Strength, HitPoints';
const list = res.split(",");
const listdata = data.split(",");
const secondlists = listdata.map(item => + item);
$('ul#response').html(list.map(item => '<li>' + item + secondlists + '</li>').join(''));
}
});
});
You can use the second param from the handler which is the index.
$('ul#response').html(list.map((item, i) => '<li>' + `${item} ${listdata[i]}` + '</li>').join(''));
^ ^
As you can see, this approach uses the array listdata directly.
I have a table containing multiple rows of data. The user can scroll through each row, click a row, and be prompted to do something with that row (update, delete, etc).
I'm able to get the id of the clicked row (the id is significant as it's the id of the model object) with Javascript and make an AJAX call to the server with the id however I can't figure out how to redirect to a page after the first server call without making a second trip to the server as AJAX needs a response.
So I'm trying to accomplish this without AJAX. Is there a way to pass the id of the row into the url (in the a-tag) of the modal below? Or is there a better pattern to accomplish this that I'm missing. This problem seems like it must have an obvious solution and I'm overthinking it...
Here's the pertinent code for my table.
Edit: I'm also using Django for my backend/template engine.
<tbody id="trip-request-table">
{% for key in need_trips %}
<tr id={{key.trip_ptr_id}} onClick="updateRow(this.id)">
<td>{{key.created|date:'Y-m-d'}}</td>
<td>{{key.user.name}}</td>
<td>{{key.arrival_date|date:'Y-m-d'}}</td>
</tr>
{% endfor %}
</tbody>
Here's the Javascript that grabs the id and fires a modal:
function updateRow(id) {
//alert('id: ' + id);
var rowId = id;
var modal = $('#manage-trip');
var row = document.getElementById(id);
var cells = row.getElementsByTagName('td');
var arrivalCity;
var departureDate;
for (var i =0; i < cells.length; i++) {
if(i == 4) {
departureDate = moment(cells[i].innerHTML).format('MMMM Do, YYYY');
} else if(i == 6) {
arrivalCity = cells[i].innerHTML;
}
}
modal.find('.modal-body').text('Would you like to update your trip to ' + arrivalCity + ' on '
+ departureDate + '?');
//updateRow.find('.modal-body input').val(id);
modal.val(id);
console.log('show modal');
modal.modal('show');
console.log('trip id: ' + id);
$("#update-trip").off().click(function(event) {
$('#manage-trip').modal('hide');
var contentType = "application/x-www-form-urlencoded";
var processData = true;
var endpoint = "{% url 'trips:updateTripGet' pk=1 %}";
var payload = false;
updateTrip(contentType, processData, endpoint, payload);
});
}
Here's the modal code:
<div class="modal" id="manage-trip" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Edit your trip</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
Update
<!--<button type="button" class="btn btn-primary" id="update-trip">Update</button>-->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#delete-trip">Delete</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
The way I solved this was by having the modal trigger this block of code:
$("#update-trip").off().click(function(event) {
$('#manage-trip').modal('hide');
var contentType = "application/x-www-form-urlencoded";
var endpoint = "{% url 'members:updateTrip' %}";
var payload = false;
//updateTrip(contentType, processData, endpoint, payload);
submitForm(contentType, endpoint, rowId);
});
That code block calls a function that dynamically creates a form and submits it to the server. I guess this is just another obvious solution to most web developers but I'm noob af. I'm sure I'll clean this up some just stoked it works.
The nice thing about this solution is you avoid having to create forms in each table row, etc.
function submitForm(contentType, endpoint, rowId) {
var form = document.createElement("form");
var element1 = document.createElement("input");
var element2 = document.createElement("input");
form.method = "POST";
form.enctype = contentType;
form.action = endpoint;
element1.type = 'hidden';
element1.value= rowId;
element1.name= "trip_id";
form.appendChild(element1);
element2.type = 'hidden';
element2.value= '{{ csrf_token }}';
element2.name= 'csrfmiddlewaretoken';
form.appendChild(element2);
document.body.appendChild(form);
form.submit();
}
I have a problem with the AngularJS two-way data binding. I'll try to explain the issue as clearly as possible: I have a list of contact names. For each element I have an Edit button. When I click on that button I load the "clicked" full Contact from an Ajax call and then I show a window with some input fields linked to the Contact just retrieved ("phone", "email" etc.). This is the interesting piece of the view:
<div>
<div class="contact" data-ng-repeat="contact in contacts">
<span>{{contact.label}}</span>
<a href="" class="btn btn-xs btn-default" data-ng-click="openContactModal(contact.ID)">
Edit
</a>
</div>
</div>
The click on the Edit button fires this function (present in the Controller):
var newContact = null;
$scope.openContactModal = function(contactID){
newContact = new Contact(contactID);
newContact.onLoad().then(
function(){
//loading OK
$('#myModal').modal('show');
},
function(){
//loading Error
}
);
$scope.newContact = newContact;
};
The call to new Contact(contactID) loads a contact from the Database with an Ajax call. I open the modal window at the end of the Ajax call (waiting for the AngularJS promise). In the modal, though, all fields are empty even though they are linked to the contact model (newContact.phone, newContact.email etc.). I've already checked that the Ajax call works fine (printing the resulted JSON). I suppose I'm missing something in the two-way data binding issue. The strange fact is that, if I try to fill the empty modal fields, the newContact model reacts well, as if the two-way data binding works well from the view to the model, but not the contrary. Thank you in advance!
EDIT: this is the service that retrieves the contact:
angular.module("app").factory("Contact", ["ContactDBServices", "$q",
function(ContactDBServices, $q){
return function(contactID){
//the contact itself
var self = this;
var contactPromise = $q.defer();
//attributi del contatto
this.firstName = null;
this.ID = null;
this.lastName = null;
this.phone = null;
this.fax = null;
this.mobile = null;
this.email = null;
this.web = null;
//the Ajax call
var metacontact = ContactDBServices.find({ID:contactID},
function(){
this.ID = contactID;
this.firstName = metacontact.contact_name;
this.lastName = metacontact.contact_last_name;
this.phone = metacontact.contact_phone;
this.fax = metacontact.contact_fax;
this.mobile = metacontact.contact_mobile;
this.email = metacontact.contact_email;
this.web = metacontact.contact_web;
//!!!THE FOLLOWING PRINTS ARE GOOD!!!!
console.log(this.ID);
console.log(this.firstName);
console.log(this.lastName);
console.log(this.phone);
console.log(this.fax);
contactPromise.resolve("OK");
},
function(){
contactPromise.reject("Error");
}
);
this.onLoad = function(){
return contactPromise.promise;
};
}
}]);
If I print the same values in the controller, though, all that values are undefined:
var newContact = null;
$scope.openContactModal = function(contactID){
newContact = new Contact(contactID);
newContact.onLoad().then(
function(){
//!!!!!!!!THE FOLLOWING PRINTS ARE ALL UNDEFINED!!!!
console.log(newContact.firstName);
console.log(newContact.lastName);
console.log(newContact.phone);
console.log(newContact.fax);
$('#myModal').modal('show');
},
function(){
//loading Error
}
);
$scope.newContact = newContact;
};
This is strange. It seems a sort of synchronization issue :-/ to be thorough here is an example piece of the modal:
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h2>Contact</h2>
</div>
<div class="modal-body">
<label>
Name
<input class="form-control" id="new_contact_name" data-ng-model="newContact.firstName" placeholder="Name">
</label>
<!-- ...and so on -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" data-ng-click="createContact()">Crea</button>
</div>
</div>
</div>
Eventually I found the mistake. It was a mistake of mine and it doesn't belong to AngularJS, but to Javascript: you'll note that, in the Contact service, I did:
//the Ajax call
var metacontact = ContactDBServices.find({ID:contactID},
function(){
this.ID = contactID;
this.firstName = metacontact.contact_name;
this.lastName = metacontact.contact_last_name;
this.phone = metacontact.contact_phone;
this.fax = metacontact.contact_fax;
this.mobile = metacontact.contact_mobile;
this.email = metacontact.contact_email;
this.web = metacontact.contact_web;
},
function(){
contactPromise.reject("Error");
}
);
clearly, writing this. in the callback function, I didn't affect the Contact values, but the function attributes! To solve this issue I had to change the callback this way:
//the Ajax call
var metacontact = ContactDBServices.find({ID:contactID},
function(){
self.ID = contactID;
self.firstName = metacontact.contact_name;
self.lastName = metacontact.contact_last_name;
self.phone = metacontact.contact_phone;
self.fax = metacontact.contact_fax;
self.mobile = metacontact.contact_mobile;
self.email = metacontact.contact_email;
self.web = metacontact.contact_web;
},
function(){
contactPromise.reject("Error");
}
);
where
var self = this;
outside the callback.