I am trying to connect my app vue with Laravel, I was able to achieve it with the "users" route but when trying to connect the second part, I can't do it, it just doesn't allow me to connect, I don't know if I'm doing things wrong, I'm new using vue.
When I connect #crudUsuarios everything works but when I connect #crudLessons data is not shown.
I tried the routes and they actually work, they return the data I want, however when connected it shows nothing.
I also get an error in the view that is not where it shows "#crudUsarios"
Error: app.js: 2626 [Vue warn]: Cannot find element: #crudUsuarios
app.js
// require('./bootstrap');
window.Vue = require('vue');
window.moment = require('moment');
window.axios = require('axios');
// import toastr from 'toastr'
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
Vue.component('example-component', require('./components/ExampleComponent.vue'));
const app = new Vue({
el: '#crudUsuarios',
created: function()
{
this.getUsers();
},
data: {
time: moment().format('Y-M-d H:mm:ss'),
users: [],
newName: '', newfLastName : '', newsLastName : '', newAge : '', newEmail: '', newCellphone : '', newPassword: '',
fillUser: {'id' : '', 'slug': '', 'name' : '','fLastName' : '','sLastName' : '','age' : '','email' : '', 'cellphone' : '', 'password' : ''},
getUser: {'id' : '', 'slug': '','name' : '','fLastName' : '','sLastName' : '','age' : '','email' : '', 'cellphone' : '', 'password' : ''},
errors: []
},
methods: {
getUsers: function()
{
//Aqui es donde conecta a la ruta para jalar los datos
var urlUsers = 'users';
axios.get(urlUsers).then(response =>{
this.users = response.data
});
},
editUser: function(user){
this.fillUser.id = user.id;
this.fillUser.name = user.name;
this.fillUser.fLastName = user.fLastName;
this.fillUser.sLastName = user.sLastName;
this.fillUser.age = user.age;
this.fillUser.email = user.email;
this.fillUser.cellphone = user.cellphone;
this.fillUser.password = user.password;
$('#edit').modal('show');
},
updateUser: function(id){
// alert('Nada man');
var url = 'users/' + id;
axios.put(url, this.fillUser).then(response => {
this.getUsers();
this.fillUser = {'id' : '','name' : '','fLastName' : '','sLastName' : '','age' : '','email' : '', 'cellphone' : '', 'password' : ''};
this.errors = [];
$('#edit').modal('hide');
toastr.success('Usuario actualizado con éxito');
}).catch(error => {
this.errors = error.response.data
});
},
deleteUser: function(user)
{
var url = 'users/' + user.id;
if (confirm("¿Eliminar usuario?") == true) {
axios.delete(url).then(response => {
this.getUsers();
toastr.success('Usuario eliminado con éxito');
});
} else {
this.getUsers();
}
},
createUser: function()
{
var url = 'users';
axios.post(url, {
name: this.newName,
fLastName: this.newfLastName,
sLastName: this.newsLastName,
age: this.newAge,
email: this.newEmail,
cellphone: this.newCellphone,
password: this.newPassword
}).then(response => {
this.getUsers();
//Vaciar los campos de creacón una vez creado el usuario.
this.newName= '', this.newfLastName= '', this.newsLastName = '', this.newAge = '', this.newEmail= '', this.newCellphone = '', this.newPassword= '',
this.errors = [];
$('#create').modal('hide');
toastr.success('Nuevo usuario creado con éxito');
// Código para que no se quede activo el MODAL
if ($('.modal-backdrop').is(':visible')) {
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();
};
}).catch(error => {
this.errors = error.response.data
});
},
showUser: function (user) {
var url = 'users/'+user.id;
axios.get(url).then(response =>{
// alert('nada de nada');
this.getUser.id = user.id;
this.getUser.slug = user.slug;
this.getUser.name = user.name;
this.getUser.fLastName = user.fLastName;
this.getUser.sLastName = user.sLastName;
this.getUser.age = user.age;
this.getUser.email = user.email;
this.getUser.cellphone = user.cellphone;
this.getUser.password = user.password;
this.getUser.created_at = user.created_at;
$('#show').modal('show');
});
}
}
});
// /var urlUsers = 'https://randomuser.me/api/?results=10';
const app = new Vue({
el: '#crudLessons',
created: function()
{
this.getLessons();
},
data: {
lessons: [],
// newName: '', newfLastName : '', newsLastName : '', newAge : '', newEmail: '', newCellphone : '', newPassword: '',
// fillUser: {'id' : '','name' : '','fLastName' : '','sLastName' : '','age' : '','email' : '', 'cellphone' : '','password' : ''},
getLesson: {'id' : '','fecha' : '','inicio' : '','final' : '', 'user_name' : '', 'user_fLastName' : '', 'user_sLastName' : '', 'user_email' : '', 'user_cellphone' : '', 'created_at' : ''},
errors: []
},
methods: {
getLessons: function()
{
//Aqui es donde conecta a la ruta para jalar los datos
var urlLessons = 'lessons';
axios.get(urlLessons).then(response =>{
this.lessons = response.data
});
},
}
});
index.blade.php
#extends('layouts.material')
#section('content')
<div class="col-lg-12" id="crudLessons">
<div class="card">
<h4> #{{ $data }} </h4>
</div>
</div>
#endsection
LessonsController.php
public function index()
{
// $products = Lesson::orderBy('id', 'DESC')->get();
$products = Lesson::with('user')->OrderBy('id', 'DESC')->get();
return $products;
}
You need to have a div with an ID corresponding to the ID you're attaching the Vue instance to using the el attribute
<div id="crudUsuarios">
#{{ data }}
</div>
Side Note
You're defining const app as a Vue Instance twice in your app.js
A constant should only exist once by the same name
Related
Im creating an online blog posting webpage that uses Sequelize and Handlebars to display the pages. The problem I am having is that I'm trying to give the user an option to update the contents of a post they have made, and I am able to change the title of the post and save it, but no matter what I do, changing the body of the post does not save as well.
Heres the code for the Post Model (/models/Post.js)
const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/connection');
// Post Model
class Post extends Model {
static upvote(body, models) {
return models.Vote.create({
user_id: body.user_id,
post_id: body.post_id,
}).then(() => {
return Post.findOne({
where: {
id: body.post_id,
},
attributes: [
'id',
'title',
'created_at',
// use raw MySQL aggregate function query to get a count of how many votes the post has and return it under the name `vote_count`
[
sequelize.literal(
'(SELECT COUNT(*) FROM vote WHERE post.id = vote.post_id)'
),
'vote_count',
],
]
})
})
}
}
Post.init(
{
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
title: {
type: DataTypes.STRING,
allowNull: false
},
post_text: {
type: DataTypes.TEXT,
allowNull: false,
validate: {
len: [4]
}
},
user_id: {
type: DataTypes.INTEGER,
references: {
model: 'user',
key: 'id'
}
}
},
{
sequelize,
freezeTableName: true,
underscored: true,
modelName: 'post'
}
);
module.exports = Post;
This is the handlebars template (views/edit-post.handlebars)
<article>
← Back to dashboard
<h2>
Edit Post
</h2>
<form class="edit-post-form">
<div>
<input name="post-title" type="text" value="{{post.title}}" />
</div>
<div>
<textarea name="post-text">{{post.post_text}}</textarea>
</div>
<div>
{{post.vote_count}} {{format_plural "point" post.vote_count}} by you on {{format_date post.created_at}}
|
{{post.comments.length}} {{format_plural "comment" post.comments.length}}
</div>
<button type="submit">Save post</button>
<button type="button" class="delete-post-btn">Delete post</button>
</form>
</article>
<form class="comment-form">
<div>
<textarea name="comment-body"></textarea>
</div>
<div>
<button type="submit">add comment</button>
</div>
</form>
{{> comments post.comments}}
<script src="/javascript/edit-post.js"></script>
<script src="/javascript/delete-post.js"></script>
<script src="/javascript/comment.js"></script>
Here's the Javascript file (/public/javascript/edit-post.js)
async function editFormHandler(event) {
event.preventDefault();
const id = window.location.toString().split('/')[
window.location.toString().split('/').length - 1
];
const title = document.querySelector('input[name="post-title"]').value;
const post_text = document.querySelector('textarea[name="post-text"]').value;
const response = await fetch(`/api/posts/${id}`, {
method: 'PUT',
body: JSON.stringify({
title,
post_text
}),
headers: {
'Content-Type': 'application/json',
},
});
if (response.ok) {
document.location.replace('/dashboard/');
} else {
alert(response.statusText);
}
}
document
.querySelector('.edit-post-form')
.addEventListener('submit', editFormHandler);
And the route function where the routes are located (controllers/dashboard-routes.js)
const router = require('express').Router();
const sequelize = require('../config/connection');
const { Post, User, Comment } = require('../models');
const withAuth = require('../utils/auth');
router.get('/', withAuth, (req, res) => {
Post.findAll({
where: {
// use the ID from the session
user_id: req.session.user_id,
},
attributes: [
'id',
'title',
'post_text',
'created_at',
[
sequelize.literal(
'(SELECT COUNT(*) FROM vote WHERE post.id = vote.post_id)'
),
'vote_count',
],
],
include: [
{
model: Comment,
attributes: ['id', 'comment_text', 'post_id', 'user_id', 'created_at'],
include: {
model: User,
attributes: ['username'],
},
},
{
model: User,
attributes: ['username'],
},
],
})
.then((dbPostData) => {
// serialize data before passing to template
const posts = dbPostData.map((post) => post.get({ plain: true }));
res.render('dashboard', { posts, loggedIn: true });
})
.catch((err) => {
console.log(err);
res.status(500).json(err);
});
});
//GET api/posts/edit/i
router.get('/edit/:id', withAuth, (req, res) => {
Post.findOne({
where: {
id: req.params.id,
},
attributes: [
'id',
'title',
'post_text',
'user_id',
'created_at',
[
`(SELECT COUNT(*) FROM vote WHERE post.id = vote.post_id)`,
'vote_count',
],
],
include: [
{
model: Comment,
attributes: ['id', 'comment_text', 'post_id', 'user_id', 'created_at'],
include: {
model: User,
attributes: ['username'],
},
},
{
model: User,
attributes: ['username'],
},
],
})
.then((dbPostData) => {
if (dbPostData) {
const post = dbPostData.get({ plain: true });
res.render('edit-post', {
post,
loggedIn: true,
});
} else {
res.status(404).end();
}
})
.catch((err) => {
console.log(err);
res.status(500).json(err);
});
});
module.exports = router;
Im pretty sure this is all of the related code but the rest is on: https://github.com/Zacharycampanelli/hi_tech_blog
I've tried changing the object the body is stored in from to and neither seem to be giving me any luck
I am beginner web developer.
I make my first application in vue project.
I have this code:
<template>
<CRow>
<CCol col="12" lg="6">
<CCard no-header>
<CCardBody>
<h3>
Create Note
</h3>
<CAlert
:show.sync="dismissCountDown"
color="primary"
fade
>
({{ dismissCountDown }}) {{ message }}
</CAlert>
<CInput label="Title" type="text" id="title" placeholder="Title" v-model="note.title"></CInput>
<CInput textarea="true" label="Content" id="content" :rows="9" placeholder="Content.."
v-model="note.content"></CInput>
<CInput label="Applies to date" type="date" id="applies_to_date" v-model="note.applies_to_date"></CInput>
<CSelect id="status_id"
label="Status"
:value.sync="note.status_id"
:plain="true"
:options="statuses"
>
</CSelect>
<CInput label="Note type" type="text" id="note_type" v-model="note.note_type"></CInput>
<template>
<div id="app">
<ckeditor v-model="editorData" :config="editorConfig"></ckeditor>
</div>
</template>
<CButton color="primary" #click="store()">Create</CButton>
<CButton color="primary" #click="goBack">Back</CButton>
</CCardBody>
</CCard>
</CCol>
</CRow>
</template>
import axios from 'axios';
import Vue from 'vue';
import CKEditor from 'ckeditor4-vue';
Vue.use(CKEditor);
export default {
name: 'EditUser',
props: {
caption: {
type: String,
default: 'User id'
},
},
data: () => {
return {
note: {
title: '',
content: '',
applies_to_date: '',
status_id: null,
note_type: '',
},
statuses: [],
message: '',
dismissSecs: 7,
dismissCountDown: 0,
showDismissibleAlert: false,
editorData: '',
editorConfig: {
// The configuration of the editor.
filebrowserImageBrowseUrl: Vue.prototype.$apiAdress+'/api/laravel-filemanager?token=' + localStorage.getItem("api_token"),
filebrowserImageUploadUrl: Vue.prototype.$apiAdress+'/api/laravel-filemanager/upload?type=Images&_token=&token=' + localStorage.getItem("api_token"),
filebrowserBrowseUrl: Vue.prototype.$apiAdress+'/api/laravel-filemanager?type=Files&token=' + localStorage.getItem("api_token"),
filebrowserUploadUrl: Vue.prototype.$apiAdress+'/api/laravel-filemanager/upload?type=Files&_token=&token=' + localStorage.getItem("api_token"),
height: 500,
language: 'pl',
//extraPlugins: 'facebookvideo, youtube, html5video',
editorUrl: "facebookvideo.js",
extraPlugins: 'a11yhelp,about,basicstyles,bidi,blockquote,clipboard,colorbutton,colordialog,contextmenu,copyformatting,dialogadvtab,div,editorplaceholder,elementspath,enterkey,entities,exportpdf,filebrowser,find,flash,floatingspace,font,format,forms,horizontalrule,htmlwriter,iframe,image,indentblock,indentlist,justify,language,link,list,liststyle,magicline,maximize,newpage,pagebreak,pastefromgdocs,pastefromlibreoffice,pastefromword,pastetext,preview,print,removeformat,resize,save,scayt,selectall,showblocks,showborders,smiley,sourcearea,specialchar,stylescombo,tab,table,tableselection,tabletools,templates,toolbar,undo,uploadimage, wysiwygarea,autoembed,image2,embedsemantic',
image2_alignClasses: ['image-align-left', 'image-align-center', 'image-align-right'],
image2_disableResizer: true,
}
}
},
methods: {
goBack() {
this.$router.go(-1)
// this.$router.replace({path: '/users'})
},
store() {
let self = this;
axios.post(this.$apiAdress + '/api/notes?token=' + localStorage.getItem("api_token"),
self.note
)
.then(function (response) {
self.note = {
title: '',
content: '',
applies_to_date: '',
status_id: null,
note_type: '',
};
self.message = 'Successfully created note.';
self.showAlert();
}).catch(function (error) {
if (error.response.data.message == 'The given data was invalid.') {
self.message = '';
for (let key in error.response.data.errors) {
if (error.response.data.errors.hasOwnProperty(key)) {
self.message += error.response.data.errors[key][0] + ' ';
}
}
self.showAlert();
} else {
console.log(error);
self.$router.push({path: 'login'});
}
});
},
countDownChanged(dismissCountDown) {
this.dismissCountDown = dismissCountDown
},
showAlert() {
this.dismissCountDown = this.dismissSecs
},
},
mounted: function () {
let self = this;
axios.get(this.$apiAdress + '/api/notes/create?token=' + localStorage.getItem("api_token"))
.then(function (response) {
self.statuses = response.data;
}).catch(function (error) {
console.log(error);
self.$router.push({path: 'login'});
});
}
}
I need add to my project validation with alert box when input is empty.
I need required for title and content. When user click button "Create" I need check this inputs. If it's empty - then I need show alert().
How can I make it?
Please help me :)
You can make method:
checkInputs() {
if(!this.note.title) {
this.message = 'pls enter title'
this.showAlert()
return true
}
if(!this.note.content) {
this.message = 'pls enter content'
this.showAlert()
return true
}
return false
}
and in store method:
store() {
if(this.checkInputs()) return
...
I'm going crazy with this error on my Android App.
I'm doing a signup in my app and I use the fetch method to an API that works. (I have tried to insert data with CocoaRestClient and it works!)
I have already done the login with the fecth and it works perfectly, but the problem is about the signup method.
So:
Registrazione.js
class Registrazione extends Component {
constructor(props) {
super(props);
this.state = {
FirstName: this.props.hasOwnProperty('FirstName') ? this.props.FirstName : '',
LastName: this.props.hasOwnProperty('LastName') ? this.props.LastName : '',
FiscalCode: this.props.hasOwnProperty('FiscalCode') ? this.props.FiscalCode : '',
identity: this.props.hasOwnProperty('identity') ? this.props.identity : '',
Email: this.props.hasOwnProperty('Email') ? this.props.Email: ''
}
}
registrazione () {
let ctrl = true;
if(ctrl){
if(global.isSafe){
Actions.sceglipassword({
Email: this.state.Email,
FirstName: this.state.FirstName,
LastName: this.state.LastName,
FiscalCode: this.state.FiscalCode
})
}
else{
Actions.creazioneutente({identity: this.state.identity, FirstName: this.state.FirstName, LastName: this.state.LastName, FiscalCode: this.state.FiscalCode, Email: this.state.Email})
}
}
};
And Then I call ScegliPassword Page:
class ScegliPassword extends Component {
constructor(props){
super(props);
this.state = {
Password: '',
PasswordRepeat: ''
};
}
registrazione(){
let ctrl = true;
if(
utility.isEmpty(this.state.Password) || utility.isEmpty(this.state.PasswordRepeat)){
ctrl = false;
Alert.alert("Error");
}
else if(this.state.Password != this.state.PasswordRepeat){
ctrl = false;
Alert.alert("Error");
}
if(ctrl)
{
let identity = {
"APPNAME":
{
Username: this.props.FiscalCode,
Password: this.state.Password
}
}
Actions.creazioneutente({identity: identity, FirstName: this.props.FirstName, LastName: this.props.LastName, FiscalCode: this.props.FiscalCode, Email: this.props.Email})
}
}
Then there is an action to CreazioneUtente
class CreazioneUtente extends Component {
constructor(props)
{
super(props)
}
creaUtenza(){
Utente.creaUtente(this.props.identity, this.props.FirstName, this.props.LastName, this.props.FiscalCode, this.props.Email)
.then((data) => {
global.utente = new Utente(data)
})
.catch((err) => {
console.log(err)
})
}
And there I call the Utente.creaUtente
static creaUtente(identity, FirstName, LastName, FiscalCode , Email) {
let formdata = new FormData();
formdata.append('Identity', identity);
formdata.append('FirstName', FirstName);
formdata.append('LastName', LastName);
formdata.append('FiscalCode', FiscalCode);
formdata.append('Email', Email);
console.log(Configuration.base_url.rest + Configuration.apiRoutes.signUp)
console.log(formdata)
return new Promise((resolve, reject)=> {
fetch(Configuration.base_url.rest + Configuration.apiRoutes.signUp , {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
},
body: formdata
})
.then((response) => response.json())
.then((responseData) => {
if(responseData.Error){
Alert.alert("Errore");
}
global.utente = responseData;
resolve(responseData)
})
.catch((err) => {reject(err)})
})
}
In the fecth I pass the link of the API for the signup (it's an https://***.com link)
Now if I print the "formdata" in console log, I receive the correct data that I have inserted with the form.
this is my AndroidManifest.xml
<application
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:roundIcon="#mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="#style/AppTheme"
xmlns:tools="http://schemas.android.com/tools"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning">
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
When I try to do the signup, I receive this kind of error (in my console):
{ _parts:
[ [ 'Identity',
{ "APPNAME": { Username: 'TNNFRZ77H01G273V', Password: '12345' } } ],
[ 'FirstName', 'Fabrizio' ],
[ 'LastName', 'Tonno' ],
[ 'FiscalCode', 'TNNFRZ77H01G273V' ],
[ 'Email', 'Fabrizio.tonno#email.com' ] ] }
{ [TypeError: Network request failed]
line: 24122,
column: 31,
sourceURL: 'http://localhost:8081/index.bundle?platform=android&dev=true&minify=false' }
I don't know how solve this problem...
Can you help me? Thank you.
I have made a customized control for the Wordpress Customizer and I would like to set my control inside a script (Instafeed.js), to change the limit number.
Following this answer this is how I did it so far
<script type="text/javascript">
var userFeed = new Instafeed({
get: '',
tagName: '',
clientId: '',
limit: var imglimit = <?php echo json_encode($imglimit); ?>;,
});
userFeed.run();
</script>
Functions
$wp_customize->add_setting(
'imglimit',
array(
'default' => '',
'section' => 'section',
));
$wp_customize->add_control('imglimit', array(
'label' => __('test'),
'section' => 'section',
'settings' => 'imglimit',
'type' => 'select',
'choices' => array(
'5' => '5',
'10' => '10',
'20' => '20',
),
));
function theme_customizer()
{
$imglimit = get_theme_mod('imglimit');
}
Could anyone tell me where is the mistake ? I've been searching for this for a while.
Well, you've got a syntax error here :)
var userFeed = new Instafeed({
get: '',
tagName: '',
clientId: '',
limit: var imglimit = <?php echo json_encode($imglimit); ?>;,
// ^^^^^^^^^^^^ here and here ^
});
So, you should change that block of code to
var userFeed = new Instafeed({
get: '',
tagName: '',
clientId: '',
limit: <?php echo json_encode($imglimit); ?>,
});
Actually you don't necessarily need to json encode here since it's just a number. But if that was some array or object, yes, you should've encoded that.
And in your php code you should make $imglimit global:
function theme_customizer()
{
global $imglimit;
$imglimit = get_theme_mod('imglimit');
}
Or just put that into js:
var userFeed = new Instafeed({
get: '',
tagName: '',
clientId: '',
limit: <?php echo json_encode(get_theme_mod('imglimit')); ?>,
});
I'm having trouble getting relationship data from localstorage when loading a model in the route.
The first time I get the data from the server through an ajax request everything is fine but as soon as I get to a new route and reload the data all the relationship have disappeard.
I don't understand how to reload these relationship! Ideally I would like to call the user-exam model and get all the hasMany array as well.
thanks for your help.
here are my two models
import DS from 'ember-data';
exam-question.js:
export default DS.Model.extend({
question : DS.attr('string'),
questionID : DS.attr('string'),
answer1 : DS.attr('string'),
answer2 : DS.attr('string'),
answer3 : DS.attr('string'),
answer4 : DS.attr('string'),
answer5 : DS.attr('string'),
answer6 : DS.attr('string'),
answer7 : DS.attr('string'),
numberOfAnswers : DS.attr('number'),
solutions : DS.attr('string'),
examID : DS.attr('string'),
chosenAnswers : DS.attr('string'),
result : DS.attr('string'),
userexam: DS.belongsTo('user-exam')
});
user-exam.js:
import DS from 'ember-data';
export default DS.Model.extend({
salesforceid : DS.attr('string'),
name : DS.attr('string'),
examType: DS.attr('string'),
resultPercentage : DS.attr('number'),
result : DS.attr('string'),
numberOfQuestions : DS.attr('number'),
rightAnswers : DS.attr('number'),
passingPercentage : DS.attr('string'),
questions: DS.hasMany('exam-question')
});
on my account.js route
import Ember from 'ember';
export default Ember.Route.extend({
model: function () {
return this.store.find('user-exam');
},
afterModel: function() {
var applicationController = this.controllerFor('application');
if (!applicationController.isLoggedIn) {
this.transitionTo('index');
}
this.controllerFor('account').send('loadData');
}
});
& controller (on first load I manage to populate all data and relationships are mapped perfectly)
import Ember from 'ember';
export default Ember.ArrayController.extend({
needs: ['application', 'newexam-modal'],
isLoading: true,
actions:{
loadData: function (){
console.log(this);
this.send('loadExamTypes');
this.send('LoadUserExams');
},
LoadUserExams: function () {
var applicationController = this.get('controllers.application');
var store = this.store;
var accountController = this;
var userexams = store.findAll('user-exam');
accountController.setProperties ({isLoading: true});
userexams.then(function() {
var userProperties = applicationController.getProperties('useremail','currentToken');
var requestdata = '{ "action": "GetExams","useremail":"'+userProperties.useremail+'","secretToken":"'+userProperties.currentToken+'"}';
Ember.$.ajax({
url: "my server url",
type: "POST",
contentType: "application/json",
data: requestdata,
success : function (data) {
//window.console.log(data);
if (userexams.content.get('length') !== data.get('length')){
data.forEach(function (item){
var examname = item.Name;
store.find('user-exam', { name: examname }).then(function(){
},function() {
console.log("items"+item);
store.createRecord('user-exam', {
salesforceid : item.Id,
name : item.Name,
resultPercentage : item.Exam_Result_Percentage__c,
result : item.Exam_Result__c,
numberOfQuestions : item.Number_of_Questions__c,
rightAnswers : item.Right_Answers__c,
passingPercentage : item.Passing_Percentage__c,
examType : item.Exam_Type__r.Name
}).save().then(function (createdexam){
console.log(item.Exam_Questions__r.records);
item.Exam_Questions__r.records.forEach(function (question){
store.createRecord('exam-question', {
question : question.Question__r.Question__c,
questionID : question.Name,
answer1 : question.Question__r.Answer_1__c,
answer2 : question.Question__r.Answer_2__c,
answer3 : question.Question__r.Answer_3__c,
answer4 : question.Question__r.Answer_4__c,
answer5 : question.Question__r.Answer_5__c,
answer6 : question.Question__r.Answer_6__c,
answer7 : question.Question__r.Answer_7__c,
numberOfAnswers : question.Question__r.Number_of_Answers__c,
solutions : question.Question__r.Solutions__c,
examID : question.Exam_Name__c,
chosenAnswers : question.Answer_Chosen__c,
result : question.Result__c,
userexam : createdexam
//store.find('user-exam', {name: item.Name})
}).save();
});
});
});
});
}
accountController.setProperties ({isLoading: false});
},
error : function (data) {
console.log(data);
}
});
});
},
deleteExamData: function() {
console.log('deleting user exams');
this.store.findAll('user-exam').then(function(record){
record.content.forEach(function(rec) {
console.log('deleting exam'+rec);
Ember.run.once(this, function() {
rec.deleteRecord();
rec.save();
});
}, this);
});
}
}
});
On my account template I use linkto to display the user-exam data. The first time I click on the button the data loads in template with all associated child records. But When I go back to account route and click on the view exam again the child records disappear
{{#link-to 'exam' this}}view exam »{{/link-to}}
here is my exam.js route
import Ember from 'ember';
export default Ember.Route.extend({
examid:'',
model: function(params){
return this.store.find('user-exam', params.exam_id);
},
serialize: function(model){
return {exam_id:model.get('id')};
},
setupController: function(controller, exam) {
controller.set('model', exam);
},
afterModel: function() {
var applicationController = this.controllerFor('application');
if (!applicationController.isLoggedIn) {
this.transitionTo('index');
}
this.controllerFor('exam').send('loadData' );
}
});
my exam.hbs
<div class="jumbotron">
<div class="container">
<h2>This is Exam: {{ name }} !</h2>
</div>
</div>
<div class="container">
{{ questions }}
{{#each question in questions}}
{{question.name}}<br />
{{/each}}
</div>
my router map:
Router.map(function() {
this.route('register');
this.route('application');
this.route('login');
this.route('account');
this.resource('exam', { path: 'exams/:exam_id' });
this.route('settings');
});
My localstorage setup is done like so with the ember-cli addon
my application.js adapter:
import DS from 'ember-data';
export default DS.LSAdapter.extend({
namespace: 'sfdquiz'
});
and serializer:
import DS from 'ember-data';
export default DS.LSSerializer.extend({
});
I was making a stupid error! question.name didn't exist.
{{#each question in questions}}
{{question.name}}<br />
{{/each}}
But I changed the pattern loading all the data at once was making the app too slow. I used the aftermodel to go fetch the related objects from the server and connect them to their parent at that moment.
model: function(params){
return this.store.find('user-exam', params.exam_id);
},
afterModel: function(exam) {
var applicationController = this.controllerFor('application');
if (!applicationController.isLoggedIn) {
this.transitionTo('index');
} else {
this.controllerFor('exam').send('loadData', exam.get('id'));
}
}